在下面的示例中,我有一个简单的Spy对象。我想创建另一个用原始对象设置原型的对象,所以我使用了Object.create()。
现在我有一个新对象,它只有原始的一些属性(' 代码'' 呼吸'方法)。所有其他属性(对象 - ' 名称'和数组 - ' 敌人')都在 _proto中 _ object,我可以使用它,因为它们被委托给原始对象。到现在为止还挺好。
棘手的部分是,如果我更改 _proto _对象中包含的AnotherSpy中的任何内容(例如,对象名称),那些更改将反映在所有从原始间谍创建的对象,包括他自己!
我也尝试使用JSON.parse()创建一个新对象,但是这样我有了一个新对象,它只能访问之前在 _proto _对象中的两件事 - 敌人和名称对象的数组,无法使用原始对象的任何方法(' 呼吸& #39;方法)。
let Spy = {
code: '007',
enemies: ['Dr.No'],
fullName: {
firstName: 'James',
lastName: 'Bond'
},
breath: function() {
console.log('im breathing..')
}
}
// original Spy breathing
Spy.breath(); // ok, he breaths
// create a new object with Object.create()
let OtherSpy = Object.create(Spy);
console.log(OtherSpy) // have direct access to properties 'code' and function 'breath' and all the others throught the __proto__ object
// Make OtherSpy breath
OtherSpy.breath(); // ok, he is breathing
// so far so good. Lets change the property and function on the OtherSpy
OtherSpy.code = '008';
OtherSpy.breath = () => {
console.log('im a new breathing')
};
OtherSpy.breath(); // ok, he's breathing differently
console.log(Spy.code); // 007 ok, original spy has the same code
Spy.breath() // ok, he stills breath in the same way.
// change the object 'name' of the OtherSpy
OtherSpy.fullName.firstName = 'Enemy';
// That change will reflect also on the original Spy...
console.log(Spy.fullName.firstName); // Enemy !!!!
// Trying in another way:
let NewSpy = JSON.parse(JSON.stringify(Spy));
console.log('NewSpy')
console.log(NewSpy) // now i dont have access to methods in the original object
NewSpy.breath() // Uncaught TypeError: NewSpy.breath is not a function

似乎 _proto _对象中包含的所有属性都在使用该原型链的所有对象中共享。
除了非常欣赏解释的这些棘手的部分之外,我想知道在JavaScript中创建对象的正确方法(不使用ES6类)以获得原型委派的优势
并且能够修改派生对象的属性和功能,而不会弄乱原始对象或任何其他派生对象。
提前致谢!
答案 0 :(得分:0)
嵌套属性有点无用,所以你可以通过使用getter / setter来展平它:
const Spy = {
firstName: "Agent",
lastName: "Unnamed",
breath(){
console.log(`${this.fullName} is breathing`);
},
get fullName(){
return this.firstName + " " + this.lastName;
},
set fullName(name){
const [first, last] = name.split(" ");
this.firstName = first;
this.lastName = last;
}
};
const james = Object.create(Spy);
james.fullName = "James Bond";
james.breath();
console.log(james.fullName, james.firstName, james.lastName);
答案 1 :(得分:0)
另一种方法是在构造函数中构造name
对象:
function Spy(name, code, enemies){
this.name = (([first, last]) => ({first, last}))(name.split(" "));
this.name.toString = () => name;
this.code = code;
this.enemies = enemies;
}
Spy.prototype = {
breath(){
console.log(`${this.name} is breathing`);
}
}
可用作:
const james = new Spy("James Bond", "007", ["Dr. No"]);
james.breath();
console.log(james.name, "" + james.name);