OOP 继承

继承:继承的本质就是原型链。

实现继承了几种方式:

1.构造函数继承:

function Parent1(){
    this.name = 'parent1';
}                                                                                                                                                                                                                                                                                                                                       Parent1.prototype.say = function(){ console.log('Parent1-say!')}
function Child1(){
    Parent1.call(this);    //call和apply方法都是用来转移上下文的(改变this的指向),使调用call方法的函数的this指向它的参数(也就是这里的this),所以Child1拥有了name属性,并且它的值是‘parent1’。
    this.sex = 'man';        call和apply方法的作用完全相同,只是他们的第二个参数不同,call的参数必须一一列举出来,而apply的参数是一个数组,也可以用arguments代替。
}
var p1 = new Child1();

     这种方式的缺点是不能继承父类原型链。

    当我们给Parent1.prototype 添加属性或方法不会被Child1继承。

2.原型链继承:

function P1() {
    this.name = 'parent1';
    this.friends = [1, 2, 3];
}
C1.prototype= new P1;   如果不传参可以不写‘()’
function C1() {
    this.sex = 'man';
}
var a1 = new C1, a2 = new C1;
console.log(a1, a2);
a1.friends.push(4);

    我们在最后一行只是给a1实例对象的friends属性添加了4,但是打印出的a2的friends也拥有这个4,这是因为他们的原型对象都指向了P1的同一个实例对象。那么这就不能满足每个实例都是独立的这个思想。

组合方式继承:

function P1() {
    this.name = 'parent1';
    this.friends = [1, 2, 3];
}
C1.prototype= new P1;
function C1() {
    P1.call(this);
    this.sex = 'man';
}
var a1 = new C1, a2 = new C1;
console.log(a1, a2);
a1.friends.push(4);

    这种方式虽然实现了每个实例之间相互隔离,但是执行了两次构造函数P1。

优化继承:

function P1() {
    this.name = 'parent1';
    this.friends = [1, 2, 3];
}
C1.prototype= P1.prototype;
C1.prototype.constructor = C1;
function C1() {
    P1.call(this);
    this.sex = 'man';
}
var a1 = new C1, a2 = new C1;
console.log(a1, a2);
a1.friends.push(4);

这种方式是最优化的继承方式。不仅继承了父类的原型链,同时也明确了自己的构造函数。

猜你喜欢

转载自blog.csdn.net/qq_25695065/article/details/79955083
OOP