2013-07-18 162 views
5

看起来好像我终于理解了JavaScript继承以及它应该如何正确完成。这里是我的代码:JavaScript和原型继承

function Human(eyes) { 
    this.eyes = eyes ? "Not blind" : "Blind"; 
} 
Human.prototype.canSee = function() { 
    return this.eyes; 
}; 
function Male(name, eyes) { 
    Human.call(this, eyes); 
    this.name = name; 
} 
Male.prototype = Object.create(Human.prototype); 
var Sethen = new Male("Sethen", true); 
console.log(Sethen.canSee()); //logs "Not blind" 

据我了解,使用Object.create创建继承原型对象比使用new关键字好得多。这在我的脑海里提出了一些问题。

  1. Male.prototype = Object.create(Human.prototype)原型链是Male.prototype --> Human.prototype --> Object.prototype --> null
  2. Male构造函数中,我使用Human.call(this, eyes);来调用一个超类,我不得不在Male构造函数中再次传递给Human构造函数。这看起来很痛苦,有没有更简单的方法来做到这一点?
  3. 为什么我有时会看到像Male.prototype = new Human();这样的代码......这似乎是不正确的。当我们这样做时究竟发生了什么?
+1

你见过这个http://stackoverflow.com/questions/13040684/javascript-inheritance-object-create-vs-new和这个http://stackoverflow.com/问题/ 4166616 /谅解 - 差异 - 对象 - 创建和新 - somefunction-in-j ??? – rafaelcastrocouto

+0

不,我没有。我会看看。 – Sethen

回答

3

回答您的问题:

  1. 这是正确的。当您设置Male.prototype = Object.create(Human.prototype)时,您将原型链设置为Male.prototype --> Human.prototype --> Object.prototype --> null。然后,当您创建var Sethen = new Male时,实例(Sethen)会从此原型链继承。
  2. 不,您需要手动将参数传递给基础构造函数。如果您想在Male函数本身内设置this.eyes = eyes ? "Not blind" : "Blind",但这只是代码重复。你在做什么是正确的。
  3. 这是旧的做事方式(在Object.create被标准化之前)。我会建议你不要使用它。对于大多数情况下,它与新方法相同。但是,使用此方法,您还会在Male.prototype上收到不需要的属性,如eyes

当我们这样做Male.prototype = new Human我们创建的Human一个新实例,并将其分配给Male.prototype。因此原型链是Male.prototype --> Human.prototype --> Object.prototype --> null。不过,我们也收到了我们不需要的财产Male.prototype.eyes。这应该只属于Male的实例。

我会建议你阅读我的博客文章。这是一个非常好的原型继承引物:Aadit M Shah | Why Prototypal Inheritance Matters

+0

谢谢你!这为我清理了一些事情。我认为我们也得到了一些不需要的属性,比如'eyes',但是不确定。 – Sethen

+0

使用Object.create辅助函数之前:http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711(仍然是如果你想支持IE 8)在这些帮助函数的构造函数可以在设置继承之后将其设置为正确的功能。如果你打算使用'constructor'属性,你仍然需要这样做。 – HMR

+1

@HMR啊。那么,我现在使用的唯一帮助函数是['augment'](https://github.com/javascript/augment)。它使用'Object.create',但你也可以在不使用'Object.create'的情况下实现它。 –