私は現在JavaからJavascriptに変換しています、そして私がそれをしたい方法でオブジェクトを拡張する方法を理解するのは少し難しいです。
私はインターネット上の何人かの人がオブジェクト上で拡張と呼ばれる方法を使うのを見ました。コードは次のようになります。
var Person = {
name : 'Blank',
age : 22
}
var Robot = Person.extend({
name : 'Robo',
age : 4
)}
var robot = new Robot();
alert(robot.name); //Should return 'Robo'
誰もがこの作品を作る方法を知っていますか?私はあなたが書く必要があると聞いた
Object.prototype.extend = function(...);
しかし、私はこのシステムを動かす方法を知りません。それが不可能な場合は、オブジェクトを拡張する別の方法を教えてください。
編集:
コードを使用する前に、単にprototype
に代入することの副作用について報告しているuser2491400からのコメントを確認してください。
元の回答:
あなたはPersonのプロトタイプオブジェクトから '継承'したいのです。
var Person = function(name){
this.name = name;
this.type = 'human';
}
Person.prototype.info = function(){
console.log("Name:", this.name, "Type:", this.type);
}
var Robot = function(name){
Person.apply(this,arguments)
this.name = name;
this.type = 'robot';
}
Robot.prototype = Person.prototype; // Set prototype to Person's
Robot.prototype.constructor = Robot; // Set constructor back to Robot
person = new Person("Bob");
robot = new Robot("Boutros");
person.info();
// Name: Bob Type: human
robot.info();
// Name: Boutros Type: robot
私はJavascriptが「新しい」ことなく生きようとするべきだと信じるキャンプにいます。それはクラスのない言語です、それはコンストラクタを必要としません。単純にオブジェクトを作成し、それからそれらを拡張または変形します。確かに、落とし穴がありますが、これははるかに強力で単純です。
// base `Person` prototype
const Person = {
name : '',
age : 22,
type : 'human',
greet() {
console.log('Hi, my name is ' + this.name + ' and I am a ' + this.type + '.' )
}
}
// create an instance of `Person`:
const skywalker = Object.create(Person)
skywalker.name = 'Anakin Skywalker'
skywalker.greet() // 'Hi, my name is Anakin Skywalker and I am a human.'
// create a `Robot` prototype by extending the `Person` prototype:
const Robot = Object.create(Person)
Robot.type = 'robot'
Robot.variant = '' // add properties for Robot prototype
// Robots speak in binaries, so we need a different greet function:
Robot.greet = function() { //some function to convert strings to binary }
// create a new instance `Robot`
const Astromech = Object.create(Robot)
Astromech.variant = 'astromech'
const r2d2 = Object.create(Astromech)
r2d2.name = 'R2D2'
r2d2.greet() // '0000111010101011100111....'
// morphing the `Robot` object doesn't affect `Person` prototypes
skywalker.greet() // 'Hi, my name is Anakin Skywalker and I am a human.'
** 10月3日の更新18。ES6の構文とconst
name__およびlet
name__の使用を採用しました。プロパティを不変にする方法を示す例を追加しました。
** 1月22日更新の17日ES6 Object.assign()を追加。
ご覧のとおり、割り当てには複数のステートメントが必要です。 ES6では、#assignメソッドを使用して割り当てを短縮できます。 (古いブラウザでpolyfillを使用するには、 ES6のMDN を参照してください。)
//instead of this
const Robot = Object.create(Person)
Robot.name = "Robot"
Robot.madeOf = "metal"
Robot.powerConsumption_kW = 5
//you can do this
const Robot = Object.create(Person)
Object.assign(Robot, {
name: "Robot",
madeOf: "metal",
powerConsumption_kWh: 5,
fullCharge_kWh: 10,
currentCharge_kWh: 5
})
//attach some methods unique to Robot prototype.
Robot.charge = function(kWh) {
let self = this
this.currentCharge_kWh = Math.min(self.fullCharge_kWh, self.currentCharge_kWh + kWh)
var percentageCharged = this.currentCharge_kWh / this.fullCharge_kWh * 100
console.log(this.name + (percentageCharged === 100) ? ' is fully charged.' : ' is ' + percentageCharged +'% charged.')
}
Robot.charge(5) // outputs "Robot is fully charged."
また、Object.create()の2番目の引数a.k.a propertiesObjectを使用することもできます。これは少し長すぎます。 #assignでこれを使用する唯一の理由は、値をもっと細かく制御する必要がある場合、つまり書き込み可能性/設定可能性などです。Robot
name__がすべて金属製であることに注意してください。
const Robot = Object.create(Person, {
madeOf: {
value: "metal",
writable: false,
configurable: false,
enumerable: true
},
powerConsumption: {
value: "5kWh",
writable: true,
configurable: true,
enumerable: true
}
})
そしてRobot
name__のすべてのプロトタイプは他のもので作ることはできません。
const polymerRobot = Object.create(Robot)
polymerRobot.madeOf = 'polymer'
console.log(polymerRobot.madeOf) // outputs 'metal'
「古典的な訓練を受けた」プログラマーを旅行する可能性が高いこのパターンへの落とし穴があります。それにもかかわらず、私はこのパターンがとても読みやすいと思います。
まだ方法がわからない場合は、JavaScriptオブジェクトのassociativeプロパティを使用して、次に示すようにObject.prototype
にextend関数を追加してください。
Object.prototype.extend = function(obj) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
this[i] = obj[i];
}
}
};
その後、以下に示すようにこの機能を使用することができます。
var o = { member: "some member" };
var x = { extension: "some extension" };
o.extend(x);
@osahyounの回答によると、Personのプロトタイプオブジェクトを「継承」するためのより効果的で効率的な方法として、次のような方法があります。
function Person(name){
this.name = name;
this.type = 'human';
}
Person.prototype.info = function(){
console.log("Name:", this.name, "Type:", this.type);
}
function Robot(name){
Person.call(this, name)
this.type = 'robot';
}
// Set Robot's prototype to Person's prototype by
// creating a new object that inherits from Person.prototype,
// and assigning it to Robot.prototype
Robot.prototype = Object.create(Person.prototype);
// Set constructor back to Robot
Robot.prototype.constructor = Robot;
新しいインスタンスを作成します。
var person = new Person("Bob");
var robot = new Robot("Boutros");
person.info(); // Name: Bob Type: human
robot.info(); // Name: Boutros Type: robot
さて、 Object.create を使って:
Person.prototype.constructor !== Robot
MDN のドキュメントも確認してください。
そしてもう一年後、私はもう一つのいい答えがあるとあなたに言うことができます。
オブジェクト/クラスを拡張するためにプロトタイピングが機能する方法が気に入らない場合は、これを見てください。 https://github.com/haroldiedema/joii
簡単なコード例の可能性(およびその他多数):
var Person = Class({
username: 'John',
role: 'Employee',
__construct: function(name, role) {
this.username = name;
this.role = role;
},
getNameAndRole: function() {
return this.username + ' - ' + this.role;
}
});
var Manager = Class({ extends: Person }, {
__construct: function(name)
{
this.super('__construct', name, 'Manager');
}
});
var m = new Manager('John');
console.log(m.getNameAndRole()); // Prints: "John - Manager"
ES6では、プロパティ値をコピーするためのObject.assign
があります。ターゲットオブジェクトを変更したくない場合は(最初のパラメータが渡された場合)、最初のパラメータとして{}
を使用します。
var resultObj = Object.assign({},Obj1,Obj2);
詳細についてはリンクを参照してください。
あなたが必要な場合ES5のためのPolyfill、リンクもそれを提供しています。 :)
あなたは nderscore.js のようなヘルパーライブラリを使うことを考えたいかもしれません---それは それはextend()
のそれ自身の実装です。
そして、それはそのソースコードを見ることによって学ぶための良い方法でもあります。 注釈付きソースコードページ はとても便利です。
シンプルでベストなアプローチにまだ苦労している人は、オブジェクトを拡張するためにSpread Syntax
を使うことができます。
var person1 = {
name: "Blank",
age: 22
};
var person2 = {
name: "Robo",
age: 4,
height: '6 feet'
};
// spread syntax
let newObj = { ...person1, ...person2 };
console.log(newObj.height);
注:一番右にあるプロパティが優先されます。この例では、person2
が右側にあるので、newObj
には名前Roboが入ります。
MozillaはECMAScript 6.0から拡張されたオブジェクトを発表します。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
注:これはECMAScript 6(Harmony)の提案の一部である実験技術です。
class Square extends Polygon {
constructor(length) {
// Here, it calls the parent class' constructor with lengths
// provided for the Polygon's width and height
super(length, length);
// Note: In derived classes, super() must be called before you
// can use 'this'. Leaving this out will cause a reference error.
this.name = 'Square';
}
get area() {
return this.height * this.width;
}
set area(value) {
this.area = value; }
}
このテクノロジはGecko(Google Chrome/Firefox) - 2015年3月3日ビルドで利用できます。
プロジェクトの大部分では、オブジェクト拡張の実装がいくつかあります。アンダースコア、jquery、lodash:extendです。
純粋なJavaScriptの実装もあります。これはECMAscript 6の一部です。Object.assign: https://developer.mozilla.org/en-US/docs)/Web/JavaScript /リファレンス/ Global_Objects/Object/assign
Function.prototype.extends=function(ParentClass) {
this.prototype = new ParentClass();
this.prototype.constructor = this;
}
その後:
function Person() {
this.name = "anonym"
this.skills = ["abc"];
}
Person.prototype.profile = function() {
return this.skills.length // 1
};
function Student() {} //well extends fom Person Class
Student.extends(Person)
var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2
JavascriptがES6からextends
キーワードをサポートするようになったため、2015年の回答は無視してください(Ecmasctipt6)
class Person {
constructor() {
this.name = "anonym"
this.skills = ["abc"];
}
profile() {
return this.skills.length // 1
}
}
Person.MAX_SKILLS = 10;
class Student extends Person {
} //well extends from Person Class
//-----------------
var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2
class Person {
static MAX_SKILLS = 10;
name = "anonym"
skills = ["abc"];
profile() {
return this.skills.length // 1
}
}
class Student extends Person {
} //well extends from Person Class
//-----------------
var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2
Javascriptはプロトタイプ継承というメカニズムを使用しています。プロトタイプ継承は、オブジェクトのプロパティを検索するときに使用されます。 JavaScriptでプロパティを拡張するときには、実際のオブジェクトからこれらのプロパティを継承しています。これは次のように機能します。
myObj.foo
やmyObj['foo']
)、JSエンジンは最初にそのオブジェクト自身でそのプロパティを探すでしょう。JavaScriptでオブジェクトから拡張したい場合は、このオブジェクトをプロトタイプチェーンで単純にリンクできます。これを実現する方法は多数あります。一般的に使用される2つの方法について説明します。
1。Object.create()
Object.create()
は、オブジェクトを引数として受け取り、新しいオブジェクトを作成する関数です。引数として渡されたオブジェクトは、新しく作成されたオブジェクトのプロトタイプになります。例えば:
// prototype of the dog
const dogPrototype = {
woof: function () { console.log('woof'); }
}
// create 2 dog objects, pass prototype as an argument
const fluffy = Object.create(dogPrototype);
const notFluffy = Object.create(dogPrototype);
// both newly created object inherit the woof
// function from the dogPrototype
fluffy.woof();
notFluffy.woof();
2。プロトタイププロパティを明示的に設定する
コンストラクタ関数を使用してオブジェクトを作成するときに、プロトタイプオブジェクトプロパティにaddプロパティを設定できます。 new
キーワードを使用したときに作成されるオブジェクトは、コンストラクター関数のプロトタイプにプロトタイプを設定します。例えば:
// Constructor function object
function Dog (name) {
name = this.name;
}
// Functions are just objects
// All functions have a prototype property
// When a function is used as a constructor (with the new keyword)
// The newly created object will have the consturctor function's
// prototype as its prototype property
Dog.prototype.woof = function () {
console.log('woof');
}
// create a new dog instance
const fluffy = new Dog('fluffyGoodBoyyyyy');
// fluffy inherits the woof method
fluffy.woof();
// can check the prototype in the following manner
console.log(Object.getPrototypeOf(fluffy));
ダウンロードの理由を追加してください
拡張するために外部ライブラリを使用する必要はありません
JavaScriptでは、すべてがオブジェクトです(3つのプリミティブデータ型を除き、さらに必要に応じて自動的にオブジェクトでラップされます)。さらに、すべてのオブジェクトは変更可能です。
JavaScriptのクラス人
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
getName: function() {
return this.name;
},
getAge: function() {
return this.age;
}
}
/* Instantiate the class. */
var alice = new Person('Alice', 93);
var bill = new Person('Bill', 30);
特定のインスタンス/オブジェクトを変更する。
alice.displayGreeting = function()
{
alert(this.getGreeting());
}
クラスを修正する
Person.prototype.getGreeting = function()
{
return 'Hi ' + this.getName() + '!';
};
あるいは単に言う:拡張JSONとOBJECTは同じである
var k = {
name : 'jack',
age : 30
}
k.gender = 'male'; /*object or json k got extended with new property gender*/
ross harmesのおかげで、dustin diaz
次のようにすれば簡単にできます。
Object.prototype.extend = function(object) {
// loop through object
for (var i in object) {
// check if the extended object has that property
if (object.hasOwnProperty(i)) {
// mow check if the child is also and object so we go through it recursively
if (typeof this[i] == "object" && this.hasOwnProperty(i) && this[i] != null) {
this[i].extend(object[i]);
} else {
this[i] = object[i];
}
}
}
return this;
};
pdate:
null
はオブジェクトなのでthis[i] != null
をチェックしました
それを次のように使います。
var options = {
foo: 'bar',
baz: 'dar'
}
var defaults = {
foo: false,
baz: 'car',
nat: 0
}
defaults.extend(options);
これは以下の結果になります。
// defaults will now be
{
foo: 'bar',
baz: 'dar',
nat: 0
}