继承的方式
原型链继承
function Person() {
this.data = [1, 2, 3];
}
function Teacher() {}
Teacher.__proto__ = Person.prototype;
var teacher = new Teacher();
teacher.data; // [1, 2, 3];
问题:
-
对于引用类型的将会共享。改变之后会引用到父的数据。
-
不能够给父构造函数传值。
构造函数继承
function Person(data) {
this.data = data;
}
function Teacher(data) {
Person.call(this, data);
}
var t = new Teacher('baibai');
t.data; // baibai
优点:
- 避免了引用类型的属性被共享问题
- 可以向父构造函数传参
缺点:都在构造函数中定义,方法每次都会被创建。
组合继承
原型链继承和构造函数继承结合。
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
console.log(this.name);
}
function Teacher(name) {
Person.call(this.name);
}
Teacher.prototype = new Person();
Teacher.prototype.constructor = Teacher;
var t = new Teacher('baibai', 18);
融合了二者的优先。
原型式继承
function createObj(o) {
function F() {};
F.prototype = o;
return new F();
}
var obj = {
name: 'www',
data: [1, 2, 3]
}
var person1 = createObj(obj);
var person2 = createObj(obj);
person1.name = 'wwww'
console.log(person1.name); // 'wwww'
这个是对 Object.create() 的模拟实现,也就是基于传入的对象为原型。
缺点:引用类型的属性值回被共享。因为共享了一个原型上的属性。
遮蔽:
如果一个普通的属性名的数据访问属性在原型链上找到了,那么赋值这个值时,一个名字为这个属性的值会直接添加到对象上。形成一个遮蔽属性。