JavaScript Object.create - 继承嵌套属性 [英] JavaScript Object.create -- inheriting nested properties

查看:95
本文介绍了JavaScript Object.create - 继承嵌套属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到过道格拉斯Crockfords Object.create方法的特殊性,我希望有人可以解释一下:

I've come across a peculiarity with Douglas Crockfords Object.create method which I'm hoping someone might be able to explain:

如果我创建一个对象 - 说'人' - 使用对象文字表示法,然后使用Object.create创建一个新对象 - 比如'anotherPerson' - 从最初的'person'对象继承方法和属性。

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.

如果我然后更改第二个对象的名称值 - 'anotherPerson' - 它也会更改初始'person'对象的名称值。

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'

使用古典风格时似乎没有出现这种嵌套问题继承与构造函数和'new'关键字。

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!?

推荐答案

这是因为 anotherPerson.name 是一个对象,它存储在原型链的上方,在原始对象上:

That 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

您可以通过为<$分配新对象来避免这种情况c $ c> name 新创建的对象的属性:

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'
};

这篇关于JavaScript Object.create - 继承嵌套属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆