JavaScript继承

JavaScript继承

原型链

  • 普通对象有__proto__和constructor
  • 函数也是对象,没有constructor,独有prototype属性

251615513677_.pic_hd_123

原型链继承

优点:原型链上的属性和方法都可以被继承

缺点:子类无法向父类传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 父类构造函数
function Father() {};
// 用于共享的方法和属性放到原型对象上
Father.prototype.say = function(msg) {
console.log('msg: ', msg);
}
Father.prototype.type = 'father';
// 子类构造函数
function Son(name) {
// 用于子类的属性和方法放到函数体内,不在原型链上
this.name = name;
};
Son.prototype = new Father(); // Son.prototype.__proto__ = Father.prototype
// Son.prototype.type = 'father';
// 实例化
var p1 = new Son('cz');
p1.say('may name is '+p1.name+',my type is '+p1.type);

借用构造函数/经典继承

优点:子类可以向父类传参

缺点:

  • 只能继承父类的实例方法和属性,无法继承原型属性和方法
  • 使用call实际上是对父类的复制,每个新实例就会复制一份
1
2
3
4
5
6
7
8
9
10
function Father(age) {
this.name = 'father';
this.age = age;
};
function Son(age) {
Persion.call(this, age);
// 借用另一个构造函数的对象和方法的构造
// 相当于 this.name = 'father'; this.age = age;
}
var one = new Son(18); // { name: 'father', age: 18 }

组合继承

结合原型链和经典继承

1
2
3
4
5
6
7
8
9
10
function Father(age) {
this.name = 'father';
this.age = age;
}
Father.prototype.say = function(msg) { console.log(msg) };
function Son(age) {
Father.call(this, age); // 借用Persion的属性和方法
}
Son.prototype = new Father();
var one = new Son(18);

原型式继承

对象浅复制,增加一层__proto__的引用,Object.create()的实现

浅复制父类的原型对象作为子类的原型对象即可实现继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function createObj(obj) {
function F() {};
F.prototype = obj;
return new F();
}
// obj1 = new Father();
// obj2 = createObj(obj1); // 基于obj1创建对象obj2
function Son() {
this.name = 'son';
};
// Son.prototype = Object.create(Father.prototype);
Son.prototype = createObj(Father.prototype);
Son.prototype.constructor = Son;
var son = new Son();
console.log(son.name); // son
son.say('hello'); // hello,继承了父类的原型方法

寄生继承

寄生:函数内返回返回对象,然后调用函数

对原型式继承二次封装,对原型式继承生成的对象进行扩展后返回

1
2
3
4
5
6
7
8
9
10
11
12
13
function creatAnother(origin) {
var clone = createObj(origin);
clone.sayHi = function() {
console.log('Hi');
}
return clone;
}
obj1 = {
name: 'obj1'
}
obj2 = creatAnother(obj1);
console.log(obj2.name); // 'obj1'
obj2.sayHi(); // Hi

寄生组合式继承

组合式继承中将父类的实例赋值给子类的原型对象的操作改为使用原型继承的方式浅复制一份父类的原型对象作为子类构造函数的原型对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function createObj(obj) {
function F() {};
F.prototype = obj;
return new F();
}
function Son(age) {
Father.call(this, age);
};
Son.prototype = createObj(Father.prototype);
Son.prototype.constructor = Son;
var son = new Son(18);
console.log(son.name); // father
console.log(son.age); // 18
son.say('hello'); // hello,继承了父类的原型方法
0%