如果我想在JavaScript中创建一个具有到另一个对象的原型链接的对象,但是它有几个自己的属性,我该怎么做呢?
var object1 = {
a: 1,
b: 2
};
var object2 = Object.create( object1 );
object2.c = 3;
object2.d = 4;
console.log( object2 ); // my new object with object1 as it's prototype link
我的挑战是我必须一次设置一个object2
的属性。
我的另一个选择是:
var object1 = {
a: 1,
b: 2
};
var object2 = {
c: 3,
d: 4
};
Object.setPrototypeOf( object2, object1 );
console.log( object2 );
我上面的挑战是表现应该是可怕的。也就是说,setPrototypeOf
很慢。 https://jsperf.com/object-create-vs-object-setprototypeof
然后,当然,你提供的“速记”,writeable
,enumerable
以及Object.create()
的所有内容,但这并不是真正的简写。
有任何想法吗?
作为Object.assign
的替代方法,请记住Object.create
接受第二个参数,其中包含要添加到对象的属性描述符:
var object1 = {
a: 1,
b: 2
};
var object2 = Object.create(object1, {
c: {value: 3, enumerable: true},
d: {value: 4, enumerable: true}
});
console.log( object2 ); // my new object with object1 as it's prototype link
请注意,默认值是不可配置的,不可写的和不可枚举的。
如果这是一个问题,ES2017引入了Object.getOwnPropertyDescriptors
。
var object1 = {
a: 1,
b: 2
};
var object2 = Object.create(object1, Object.getOwnPropertyDescriptors({
c: 3,
d: 4
}));
console.log( object2 ); // my new object with object1 as it's prototype link
您可以将Object.create
与Object.assign
结合使用:
var object2 = Object.assign(Object.create(object1), {
c: 3,
d: 4
});
通常,当我们讨论设置和交换原型时,我们讨论的是构造函数,它们被实例化为对象而不是对象文本本身。
你当然可以在这种情况下手动切换原型(这是原型继承的基础)并且会导致你继承正确的属性,但是你现在还必须在派生对象的实例被制作时处理构造函数问题。
但是,这种技术很快,因为它只需要创建一个新实例,然后在prototype属性中设置引用。
function object1(){
this.a = 1;
this.b = 2;
console.log("object1 has been invoked");
};
function object2(){
console.log("object2 has been invoked");
this.c = 3;
this.d = 4;
};
// It's very important that the prototype be set to a NEW instance
// of the super-object so that you don't wind up sharing a prototype
// with other unintended objects.
object2.prototype = new object1();
// object2.prototype.constructor was the function object2
// But now that object2 has had its prototype swapped out
// to object1, when new instances of object2 are made, the
// constructor for object1 will execute. To fix this, we
// just need to reset the constructor property of the new
// prototype that we just set. That's another reason we created
// a new instance of object1, so we could modify the constructor
// of that instance without screwing up other instances of object1
// that may be in use. object2 will use object1 as
// it's prototype, but that particular instance of object1
// will have object2 set as the constructor to use when instances
// are needed.
object2.prototype.constructor = object2;
console.log( new object2() );