1.call的借用继承
function parent1() {
this.name = "parent1"
}
function child1() {
parent1.call(this)
this.type = 'child1'
}
parent1.prototype.say = function () {
console.log('hi parent1')
}
var s1 = new child1();
console.log(s1); //{name: "parent1", type: "child1"}
console.log(s1.say()); //Uncaught TypeError: s1.say is not a function
上述代码中,关于在parent1中的属性,可以给子级继承,但是在parent1原型链上的方法,无法给子级继承。
2. 原型链继承
function parent2() {
this.name = 'parent2';
this.arr = [1,2,3];
}
function child2 () {
this.type = 'child2';
}
parent2.prototype.say = function () {
console.log('hi parent2');
}
child2.prototype = new parent2();
var a1 = new child2();
var a2 = new child2();
a1.say() // hi parent2
a2.say() // hi parent2
a1.arr.push(4);
console.log(a1.arr, a2.arr); // [1, 2, 3, 4], [1, 2, 3, 4]
上述代码中,child2构造函数的prototype属性指向父级实例,子级实例中可以使用say方法,但是缺点是child2原型上的属性值,所有实例皆可访问。修改了一个实例,其他的都发生改变
3.组合继承
function parent3() {
this.name = 'parent3';
this.arr = [1,2,3];
}
function child3() {
parent3.call(this);
this.type = 'child3';
}
parent3.prototype.say = function () {
console.log('hi parent3');
}
child3.prototype = new parent3();
var a3 = new child3();
var a4 = new child3();
a3.say(); a4.say() // hi parent3
a3.arr.push(4);
console.log(a3, a4); //[1, 2, 3, 4], [1, 2, 3]
上述代码中,使用call借用继承属性值,使用原型链继承其中方法
4. 组合继承的优化1
在3中的代码中,因为属性已经被call继承,所以原型链中不需要再次继承, 所以将
child3.prototype = parent3.prototype // 其他部分不变
5.组合继承的优化2
在优化之前,先介绍一个创建对象的方法,Object.create可创建一个新对象,使用现有对象来为新对象提供__proto__
var p1 = {"name": ''};
var obj = Object.create(p1);
console.log(obj);
开始优化:
当对3和4中代码打印时
console.log(a3 instanceof parent3, a3 instanceof child3);
console.log(a3.constructor);
它们的构造器都是parent3,父级构造,我们知道a3实例是由child3构造出的。所以要改变constructor的指向问题
function parent5() {
this.name = 'parent5';
this.arr = [1,2,3];
}
function child5() {
parent5.call(this);
this.type = 'child5';
}
parent5.prototype.say = function () {
console.log('hi parent5');
}
child5.prototype = Object.create(parent5.prototype); //原型指向一个空对象实例,空对象的__proto__指向parent5.prototype
child5.prototype.constructor = child5;
var s3 = new child5();
var s4 = new child5();
s3.say(); s4.say() // hi parent5
s3.arr.push(4);
console.log(s3, s4); //[1, 2, 3, 4], [1, 2, 3]