理解Javascript原型继承

时间:2015-05-16 22:12:11

标签: javascript inheritance

我害怕提出这个问题,因为在同一主题上有这么多人。

我想了解使用callapproach-1

的缺点/局限性

简单继承

approach-2

3 个答案:

答案 0 :(得分:1)

在基于原型的语言中,继承是通过克隆作为原型而不是类的现有对象来执行的。

因此,在每种情况下,我们都应该考虑选择用作原型来确定行为的对象。

在方法1中,您将Student的原型设置为与Person相同的原型对象。这意味着对Student.prototype所做的任何更改都会影响Person.prototype,反之亦然。

在方法2中,您将Student的原型设置为新的Person对象,该对象将根据您的初始化代码设置{name: 'de-name', age: 0}以下属性。然后,您通过调用Person.call()函数中的Student来覆盖名称属性。由于这是一个全新的对象,对Student.prototype的任何修改都只会影响新的Student对象,并且作为原型的Person实例上的任何缺失属性都将委托给Person.prototype

详细说明最后一点(缺少属性传递给原型链),这是一个例子。假设我们向greet添加了一个新方法Person

Person.prototype.greet = function() { console.log("Hi! " + this.name; ) }

调用new Student().greet()将通过原型链进行JavaScript检查,直到它到达相应的属性(否则会得到未定义的错误。)

// Walking up the chain
/* 1 */ new Student()     // doesn't have a greet property
/* 2 */ Student.prototype // => Person {name: 'de-name', age: 0}
// This person instance doesn't have a greet property either
// because we instantiated it before adding the `greet` property
/* 3 */ Person.prototype  // Has a greet property which gets called

在使用Object.create的建议模式中,除了Student.prototype = new Person()允许您执行differential inheritance之外,您与Object.create几乎完全相同。您甚至可以添加其他属性作为其第二个参数:

Student.prototype = Object.create(Person.prototype, {
  age: 16,
  study: function() { console.log("But I'm sooo lazy!!!"); } 
});

答案 1 :(得分:0)

方法1和方法2实际上并不完全相同。在方法2中,您正在创建Person的新实例,并将该新实例分配给Student的原型。

此外,你应该这样做:

var Student = Object.create(Person.prototype);

根据MDN

The Object.create() method creates a new object with the specified prototype object and properties.

因此,您不将其分配给学生原型,将其分配给学生本身,并且学生将Person作为其原型。

答案 2 :(得分:0)

approach-2表示原型链中的另一个对象。如果(new Student()).someAttr在学生对象(new Student())中没有解决,则使用方法2,检查人物对象(new Person())(因为那是' s&# 39; s在Student.prototype),然后是Person.prototype。使用方法1,没有人对象。