admin管理员组文章数量:1208155
I've come across a peculiarity with Douglas Crockfords Object.create method which I'm hoping someone might be able to explain:
If I create an object - say 'person' - using object literal notation then use Object.create to create a new object - say 'anotherPerson' - which inherits the methods and properties from the initial 'person' object.
If I then change the name values of the second object - 'anotherPerson' - it also changes the name value of the initial 'person' object.
This only happens when the properties are nested, this code should give you an idea of what I mean:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
};
// initiate new 'person' object
var person = {
name: {
first: 'Ricky',
last: 'Gervais'
},
talk: function() {
console.log('my name is ' + this.name.first + ' ' + this.name.last);
}
}
// create anotherPerson from person.prototype
var anotherPerson = Object.create(person);
// change name of anotherPerson
anotherPerson.name.first = 'Stephen';
anotherPerson.name.last = 'Merchant';
// call talk method of both 'person' and 'anotherPerson' objects
person.talk(); // oddly enough, prints 'Stephen Merchant'
anotherPerson.talk(); // prints 'Stephen Merchant'
If I were to store the name values without nesting then this odd behaviour does not occur -- e.g.
// initiate new 'person' object
var person = {
firstName: 'Ricky',
lastName: 'Gervais',
talk: function() {
console.log('my name is ' + this.firstName + ' ' + this.lastName);
}
}
// create anotherPerson from person.prototype
var anotherPerson = Object.create(person);
// change name of anotherPerson
anotherPerson.firstName = 'Stephen';
anotherPerson.lastName = 'Merchant';
// call talk method of both 'person' and 'anotherPerson' objects
person.talk(); // prints 'Ricky Gervais'
anotherPerson.talk(); // prints 'Stephen Merchant'
This nesting issue doesn't seem to occur when using a classical style of inheritance with a constructor function and the 'new' keyword.
I'd be much appreciative if anyone's able to explain why this occurs!?
I've come across a peculiarity with Douglas Crockfords Object.create method which I'm hoping someone might be able to explain:
If I create an object - say 'person' - using object literal notation then use Object.create to create a new object - say 'anotherPerson' - which inherits the methods and properties from the initial 'person' object.
If I then change the name values of the second object - 'anotherPerson' - it also changes the name value of the initial 'person' object.
This only happens when the properties are nested, this code should give you an idea of what I mean:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
};
// initiate new 'person' object
var person = {
name: {
first: 'Ricky',
last: 'Gervais'
},
talk: function() {
console.log('my name is ' + this.name.first + ' ' + this.name.last);
}
}
// create anotherPerson from person.prototype
var anotherPerson = Object.create(person);
// change name of anotherPerson
anotherPerson.name.first = 'Stephen';
anotherPerson.name.last = 'Merchant';
// call talk method of both 'person' and 'anotherPerson' objects
person.talk(); // oddly enough, prints 'Stephen Merchant'
anotherPerson.talk(); // prints 'Stephen Merchant'
If I were to store the name values without nesting then this odd behaviour does not occur -- e.g.
// initiate new 'person' object
var person = {
firstName: 'Ricky',
lastName: 'Gervais',
talk: function() {
console.log('my name is ' + this.firstName + ' ' + this.lastName);
}
}
// create anotherPerson from person.prototype
var anotherPerson = Object.create(person);
// change name of anotherPerson
anotherPerson.firstName = 'Stephen';
anotherPerson.lastName = 'Merchant';
// call talk method of both 'person' and 'anotherPerson' objects
person.talk(); // prints 'Ricky Gervais'
anotherPerson.talk(); // prints 'Stephen Merchant'
This nesting issue doesn't seem to occur when using a classical style of inheritance with a constructor function and the 'new' keyword.
I'd be much appreciative if anyone's able to explain why this occurs!?
Share Improve this question edited Jan 31, 2013 at 12:24 hippietrail 17k21 gold badges109 silver badges178 bronze badges asked Jul 7, 2010 at 0:17 RichardRichard 3833 silver badges11 bronze badges 1- 2 possible duplicate: Crockford's Prototypal inheritance - Issues with nested objects – Bergi Commented Jun 8, 2014 at 12:59
3 Answers
Reset to default 20That happens because anotherPerson.name
is an object and it is stored upper in the prototype chain, on the original person
object:
//...
var anotherPerson = Object.create(person);
anotherPerson.hasOwnProperty('name'); // false, the name is inherited
person.name === anotherPerson.name; // true, the same object reference
You can avoid this by assigning a new object to the name
property of the newly created object:
// create anotherPerson from person
var anotherPerson = Object.create(person);
anotherPerson.name = {
first: 'Stephen',
last: 'Merchant'
};
The problem is that Object.create only does a shallow copy, not a deep copy, so person.name and anotherPerson.name both point to the same Object instance.
Edited
While it's true that person.name === anotherPerson.name
, my explanation for why this is true is incorrect. See @CMS's answer for the correct explanation.
The reason the name
attribute isn't copied is because object literals in JavaScript are always references, therefore the reference is copied (not its content) ... so it is not because it is deeper in the prototype chain or because it's doing a shallow copy.
本文标签: JavaScript Objectcreateinheriting nested propertiesStack Overflow
版权声明:本文标题:JavaScript Object.create -- inheriting nested properties - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738680950a2106548.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论