繁体   English   中英

了解Javascript原型继承

[英]Understanding Javascript prototypical inheritance

恐怕要问这个问题,因为在同一主题上已经有很多这样的问题。

我试图了解使用approach-1approach-2缺点/局限性

简单继承

 function Person(name, age) { this.name = name || "de-name"; this.age = !!Number(age) ? Number(age) : 0; } Person.prototype.setName = function(name) { this.name = name; return this; } function Student(name) { Person.call(this, name); // Copy instance properties of Person class this.title = "Student"; } // Suggested way Student.prototype = Object.create(Person.prototype); // Possible approach-1 // Student.prototype = Person.prototype; // Possible approach-2 // Student.prototype = new Person(); 

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

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

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

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

为了详细说明最后一点(缺少的属性在原型链中传递),下面是一个示例。 假设我们添加一个新的方法greetPerson

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()几乎相同,只是Object.create允许您执行差异继承 您甚至可以添加其他属性作为其第二个参数:

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

实际上,方法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.

因此,您无需将其分配给Student原型,而是将其分配给Student本身,然后Student获得Person作为其原型。

Approach-2表示原型链中的另一个对象。 如果(new Student()).someAttr没有在学生对象( new Student() )中解析,则采用方法2,将检查人员对象( new Person() )(因为这是Student.prototype ),然后Person.prototype 使用方法1时,没有人对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM