JavaScript对象继承

5

请帮忙理解这段代码。

var person = {
    'first-name': 'FirstName',
    'last-name': 'LastName',
    'gender': 'Male'
};

var anotherPerson = new Object(person);
anotherPerson.desig = 'Designation';

console.log('Another person designation: ' + anotherPerson['desig'] + ', person designation: ' + person['desig']);

我原以为输出结果应该是Another person designation: Designation, person designation: undefined,但令我惊讶的是结果居然是`Another person designation: Designation, person designation: Designation

根据我的理解,anotherPerson 是继承了 person 对象,并且赋值给 anotherPerson 的属性不应该对 person 对象可见。但是我错了吗?或者这两个对象都指向同一位置吗?

[编辑]

现在还有更多意外的事情发生了。

我在上述代码中添加了以下代码:

person.place = 'XYZ';
console.log(person['place'] + ', ' + anotherPerson['place']); // Expected: XYZ, undefined. Result: XYZ, XYZ.

根据上述结果和答案,我认为这两个对象都指向同一位置。现在我添加了几行代码。

person = undefined;
console.log(anotherPerson['place']) //Expected: error, Result: XYZ. ??!?!?
console.log(person['place']) // Expected: error, Result: error.

有人能为我解释一下这个吗?感谢您的帮助。


这里没有继承。只是对同一对象的两个引用。 - Cameron
那么你如何克隆对象并创建一个新对象呢?我和原帖作者可能一样,认为new会创建一个全新的对象。 - DanRedux
请参见:https://dev59.com/A3RB5IYBdhLWcg3wET5J - Kendall Frey
Object.create() 是正确的方式 http://ncombo.wordpress.com/2013/07/11/javascript-inheritance-done-right/ - Jon
5个回答

2

您没有进行扩展或任何形式的继承。

这更接近于:

var Person = function () {
    this["first-name"] = 'FirstName',
    this["last-name"] = 'LastName',
    this["gender"] = 'Male'
};

var person = new Person();
var anotherPerson = new Person();

现在你有两个Person独立实例。如果你也想让anotherPerson成为一个子类..
var Person = function () {
    this["first-name"] = 'FirstName',
    this["last-name"] = 'LastName',
    this["gender"] = 'Male'
};

var AnotherPerson = function () {
    this.desig = "Designation";
}
AnotherPerson.prototype = new Person();   // inherit from Person
AnotherPerson.prototype.constructor = AnotherPerson;  // reset constructor

var person = new Person();
var anotherPerson = new AnotherPerson();

console.log(person.desig); // undefined
console.log(anotherPerson.desig); // Designation

1
我刚刚完成了编写相同的第一个代码块 ;) +1 - bhamlin
@Frits 谢谢您的回复。我已经理解了您所解释的代码。那么当我们执行 new Object(person) 时,anotherPerson 是不是指向同一个位置?我尝试给 person 添加一个新属性,anotherPerson 成功读取了这个新属性。为什么会这样呢? - Anji
我不完全确定new Object(person)的作用是什么...也许它只是解析为person? 我确实知道它不会神奇地从person扩展:P - Halcyon
@FritsvanCampen 嗯,非常奇怪。当这种结果出现时,我有时会怀疑自己是否真正懂JavaScript。 - Anji
我不喜欢 JavaScript 中本地原型的工作方式,据说它也有内存泄漏问题!找一个框架来为你实现继承。 - Halcyon

0

虽然不是一个完美的解决方案,但对我来说,这是如何克隆一个对象并使其可扩展的方法:

var anotherPerson = new Object();
for(i in person) anotherPerson[i]=person[i];

不是

var anotherPerson = new Object(person);

然后它按预期工作。


我可以知道当我们执行 var anotherPerson = new Object(person) 时会发生什么吗? - Anji

0
如果您想扩展/继承一个对象,那么可以这样做:
var person = {
    'first-name': 'FirstName',
    'last-name': 'LastName',
    'gender': 'Male'
};
if (typeof Object.create !== 'function')
{
    Object.create=function(o)
    {
        function F(){}
        F.prototype=o;
        return new F();
    }
}
var newPerson=Object.create(person);
newPerson.age=25;
newPerson.gender="Female";

console.log(person.gender); // Male
console.log(newPerson.gender); // Female

console.log(person.age); // undefined
console.log(newPerson.age); // 25

Fiddle

参考: JavaScript中的原型继承


道格拉斯·克罗克福特的方式!完美。 - Anji

0

Object函数(注意:如果您不熟悉情况,甚至更令人惊讶的是调用new Object(...)也是一样的)如果传递的参数不是布尔值、数字或字符串类型,则不会创建新对象;它只返回已经存在的对象。(原因是:因为它已经是一个对象了。在Javascript中几乎所有东西都是对象。)

因此,anotherPersonperson是完全相同的对象,所以当您修改它时,也会修改person

我不认为这是合理的行为;但这就是语言规范定义的。


0

JavaScript中实现继承的通用解决方案

function inherits(base, extension)
{
   for ( var property in base )
   {
      try
      {
         extension[property] = base[property];
      }
      catch( warning ){}
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接