ES5中常用的继承

目录

1. 原型链继承:

 2.  构造继承:在子类的构造函数中调用父类函数

3. 组合继承:

4.  寄生组合式继承:


1. 原型链继承:

        子类构造函数的原型对象指向父类构造函数的实例

     缺点: 1.子类的实例会共享父类的引用类型的属性

                 2. 调用父类方法的时候无法向父类传递参数

// 父类

function SuperClass() {

    // 引用属性

    this.books = ['javaScript', 'css世界', 'html'];

    // 普通属性

    this.superValue = true;

}

SuperClass.prototype.getBooks = function() {

    return this.books;

}

// 子类

SuperClass.prototype.superName = 'super';

    function SubClass(name) {

    this.name = name

    this.subValue = false;

}

SubClass.prototype = new SuperClass();

    // 子类自己的方法

    SubClass.prototype.getSubValue = function() {

    return this.subValue;

}

// 测试例子

var instance1 = new SubClass('instance1');

var instance2 = new SubClass('instance2');

console.log(instance1.books); //["javaScript", "css世界", "html"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "css世界", "html", "数据结构"]

console.log(instance2.books); //["javaScript", "css世界", "html", "数据结构"]

// instanceof 判断一个对象是否是一个类的实例,或一个对象是否继承一个类

console.log(instance1 instanceof SubClass); // true

console.log(instance1 instanceof SuperClass); // true

console.log(SubClass instanceof SuperClass); // false

console.log(SubClass.prototype instanceof SuperClass); // true

console.log(instance1.superName); //super

 2.  构造继承:在子类的构造函数中调用父类函数

      缺点: 1. 无法继承父类的原型属性和原型方法

      优点: 1. 解决了原型继承中子类实例共享父类引用属性的问题;  2. 调用父类构造函数时无法传递参数的问题

*/

// 父类

function SuperClass(id) {

    // 引用属性

    this.books = ['javaScript', 'css世界', 'html'];

    // 普通属性

    this.superValue = true;

    this.id = id;

}

SuperClass.prototype.getBooks = function() {

    return this.books;

}

SuperClass.prototype.name = 'super'

// 子类

function SubClass(id) {

    this.subValue = false;

    SuperClass.call(this, id);

}

// 测试例子

var instance1 = new SubClass('instance1')

var instance2 = new SubClass('instance2')

console.log(instance1.books); //["javaScript", "css世界", "html"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

console.log(instance2.getBooks); //undefined

console.log(instance2.superName); //undefined

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "css世界", "html", "数据结构"]

console.log(instance2.books); //["javaScript", "css世界", "html"]

console.log(instance1.id); //instance1

console.log(instance2.id); //instance2

/*

3. 组合继承:

原型继承+构造继承(即在子类的构造函数中执行父类构造函数,将子类的原型对象指向为父类的实例)

优点: 1. 可以向父类构造函数中传递参数; 2. 子类的实例不会共享父类的引用属性;  3. 子类可以继承父类的原型属性和原型方法

缺点:父类构造函数执行了两次

// 父类

function SuperClass(name) {

    this.name = name;

    this.books = ['javaScript', 'CSS世界', 'html布局大全'];

}

// 父类原型方法

SuperClass.prototype.getName = function() {

    return this.name;

}

SuperClass.prototype.superValue = true;

// 子类

function SubClass(name, price) {

    SuperClass.call(this, name); //第二次调用父类构造函数(在新对象上创建了实例属性,会屏蔽掉原型上同名的属性)

    this.price = price;

}

SubClass.prototype = new SuperClass(); //第一次调用父类构造函数(此时父类的实例属性和原型属性均会在子类的原型上)

// 修改子类的原型对象破坏了constructor属性,所以对constructor重新赋值

SubClass.prototype.constructor = SubClass;

// 测试例子

var instance1 = new SubClass('instance1', 65.6);

console.log(instance1.getName()); //instance1

console.log(instance1.books); //["javaScript", "CSS世界", "html布局大全"]

instance1.books.push('数据结构');

console.log(instance1.books); //["javaScript", "CSS世界", "html布局大全", "数据结构"]

console.log(instance1.superValue); //true

var instance2 = new SubClass('instance2', 86.8);

console.log(instance2.getName()); //instance2

console.log(instance2.books); //["javaScript", "CSS世界", "html布局大全"]

console.log(instance2.superValue); //true

/*

4.  寄生组合式继承:

寄生式继承 + 构造继承

优点: 1. 父类构造函数只需要执行一次;2. 解决父类实例属性即在子类的原型上存在,又在子类的实例属性上存在;

// 创建一个空的过渡函数,让其继承父类构造函数,并返回过渡函数的一个实例

// 目的: 用于继承父类原型属性和原型方法

function inheriteObject(obj) {

    function F() {}

    F.prototype = obj;

    return new F();

}

/*

寄生式继承,继承原型

**/

function inheritPrototype(subClass, superClass) {

    var p = inheriteObject(superClass.prototype);

    // 原本的 p.constructor === SuperClass

    p.constructor = subClass;

    subClass.prototype = p;

}

// 父类

function SuperClass(name) {

    this.name = name;

    this.books = ['javaScript','css世界','html布局大全'];

}

SuperClass.prototype.getName = function() {

    return this.name;

}

// 子类

function SubClass(name, price) {

    // 构造函数式继承,(继承父类的实例属性和实例方法)

    SuperClass.call(this, name);

    this.price = price;

}

inheritPrototype(SubClass, SuperClass);

// 测试例子

var instance1 = new SubClass('css世界', 45)

console.log(instance1.books); //["javaScript", "css世界", "html布局大全"]

instance1.books.push('数据结构与算法')

console.log(instance1.books); // ["javaScript", "css世界", "html布局大全", "数据结构与算法"]

var instance2 = new SubClass('javaScript设计模式', 55)

console.log(instance2.books); //["javaScript", "css世界", "html布局大全"]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wen_文文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值