2016-12-07 2 views
0

Если я хочу создать объект в JavaScript, который имеет ссылку прототипа на другой объект, но имеет несколько своих свойств, как я могу это сделать?Сокращение для Object.create() с несколькими свойствами

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 «s один на один раз.

Мой другой вариант:

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(), но это на самом деле не стенографии.

Любые идеи?

+0

Вы всегда 'вар object2 = Object.assign (Object.create (object1), {C: 3, г: 4}));'? – loganfsmyth

+0

На самом деле, это один из приемлемых вариантов использования для объекта.setPrototypeOf', и довольно легко оптимизируется. Если это слишком медленно для вас, вы должны указать проблему у своего поставщика браузера. – Bergi

ответ

1

Обычно, когда мы говорим о настройке и замене прототипов, мы говорим о конструкторских функциях, которые создаются в объектах, а не в самих объектных литералах.

Вы можете, конечно, вручную переключить прототип самостоятельно в этом случае (который является основой для прототипического наследования) и заставит вас наследовать правильные свойства, но теперь вам также приходится иметь дело с проблемами конструктора, когда экземпляры ваших производный объект.

Но эта техника выполняется быстро, так как требуется только создание нового экземпляра, и эта ссылка затем устанавливается в свойстве прототипа.

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());

2

Вы можете комбинировать Object.create с Object.assign для этого:

var object2 = Object.assign(Object.create(object1), { 
    c: 3, 
    d: 4 
}); 
2

В качестве альтернативы 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