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
不算标准的继承模式
- 不能继承借用构造函数的原型
- 每次构造函数都要多走一个函数 ==>浪费效率
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();
可以用上面的方式封装函数,实现一个继承
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();
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();
son._proto_ --> new F()._proto_ --> Father.prototype
原型上默认有个 constructor
constructor 默认指向他的构造函数
son. constructor 应该指向 Son
指向 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;
}
}());