JavaScript——继承

JS继承

1.传统形式 ==> 原型链

问题:过多的继承了没用的属性

Grand.prototype.lastName = 'Ji';

function Grand() {
     

}
var grand = new Grand();

Father.prototype = grand;

function Father() {
     
	this.name = 'hehe';
}
var father = new Father();
Son.prototype = father;

function Son() {
     

}
var son = new Son();

2.借用构造函数 ==> 利用 call、apply

不算标准的继承模式

  1. 不能继承借用构造函数的原型
  2. 每次构造函数都要多走一个函数 ==>浪费效率
function Person(name, age, sex) {
     
    this.name = name;
    this.sex = sex;
    this.age = age;
}

function Student(name, age, sex, grade) {
     
    Person.call(this, name, age, sex);
    this.grade = grade;
}
var person = new Student();

3.共享原型(较好的继承方法)

Father.prototype.lastName = 'Deng';

function Father() {
     

}

function Son() {
     

}
Son.prototype = Father.prototype;
var son = new Son();
var father = new Father();

JavaScript——继承_第1张图片

可以用上面的方式封装函数,实现一个继承
extend 和 inherit 都是继承的意思。
inherit 是 css 的一个值,也是继承的意思。

文字类属性都有一个传递的特性:子元素没有设置文字类属性,子元素默认继承父元素的属性。

在 inherit(Target,Origin)里面传进去的值是构造函数,需要大驼峰式书写,origin是原始的意思,让 target(目标)继承 origin

下面这种写法,son.prototype 和 father.prototype 指向的是一个房间,改 son 就改了father。我们希望 son 用的 father 的原型,但是改变 son 自己的属性不影响 father

Father.prototype.lastName = 'Deng';

function Father() {
     

}

function Son() {
     

}

function inherit(Target, Origin) {
     
		Target.prototype = Origin.prototype;
}

inherit(Son, Father);

Son.prototype.sex = 'male';
var son = new Son();
var father = new Father();

JavaScript——继承_第2张图片

4.圣杯模式

圣杯模式是在方法三的共有原型,但是在共有原型的基础上有改变。
共享原型是:son.prototype=father.prototype

圣杯模式是:另外加个构造函数 function F(){}当做中间层,然后让 F 和 father 共有一个原型 F.prototype=father.prototype,然后 son.prototype = new F();使用原型链形成了继承关系,现在改 son.prototype 就不会影响 father.prototype

function Father() {
     

}

function Son() {
     

}
Father.prototype.lastName = 'Deng';
function inherit(Target, Origin) {
     
    function F() {
     };
    F.prototype = Origin.prototype;
    Target.prototype = new F();
  	// 让子类的constructor重新指向自己,若不修改则会发现constructor指向的是父类的构造函数
    target.prototype.constructor = target;
}

inherit(Son, Father);
var son = new Son();
var father = new Father();

JavaScript——继承_第3张图片

son._proto_ --> new F()._proto_  --> Father.prototype

原型上默认有个 constructor
constructor 默认指向他的构造函数
son. constructor 应该指向 Son
JavaScript——继承_第4张图片

指向 father 就是混乱了
所以要指一下

我们希望我们构造出的对象,能找到自己的超类,超级父级(究竟继承自谁)应该起名为super 但这个是保留字,我们就以 uber

function Father() {
     

}

function Son() {
     

}
Father.prototype.lastName = 'Deng';
function inherit(Target, Origin) {
     
    function F() {
     };
    F.prototype = Origin.prototype;
    Target.prototype = new F();
  	Target.prototype.constructor = Target;
		Target.prototype.uber = Origin.prototype;
}

inherit(Son, Father);
var son = new Son();
var father = new Father();

建议使用的圣杯模式

var inherit = (function () {
     
    var F = function () {
     };
    return function (Target, Origin) {
     
        F.prototype = Origin.prototype;
        Target.prototype = new F();
        Target.prototype.constructor = Target;
        Target.prototype.uber = Origin.prototype;
    }
}());

你可能感兴趣的:(#,Javascript,javascript,ecmascript,继承)