【JavaScript】ES5实现继承的几种方案

原形链继承

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sleeping = function() {
        console.log(`${this.name} is sleeping.`)
    }
}

function Student(name, age) {
	Person.call(this, name, age);
	this.studying = function() {
		// ...
	}
}

Student.prototype = new Person();

这种继承方法的主要缺点有:

  1. Person 构造函数被调用多次
  2. 无法打印原形上的属性

寄生式继承

对象的寄生式继承

先来看直接赋值 prototype 的情况:

Student.prototype = Person.prototype;

Student.prototype.running = function() {
	// ...
}

这会导致添加在 Student 原型上的属性被添加到其父类 Person 上,且后面所有 Person 的子类都会有添加在 Student 原形上的属性,显然这种做法是错误的。

既然直接指向 prototype 不可取,那么我们可以添加一个中间对象,这个对象的 prototype 指向我们要继承的父类,然后父类的子类的 prototype 指向我们创建出来的中间对象。这样当我们给子类的 prototype 添加属性时,实际上上是添加到我们创建出来的中间对象上了,不会影响父类的 prototype,这种方法被称为寄生式继承

先来看对象的寄生式继承:

const person = {
	name: 'xxx',
	age: 18
}

function createObject(o) {
    const newObj = {};
    // 获取 o 的原形对象
    const pt = Object.getPrototypeOf(o);
    // 设置创建出来的空对象的原形为 o 的原形
    Object.setPrototypeOf(newObj, pt);
	return newObj;
}

const stu = createObject(person);
stu.name = '1111';
console.log(stu.name, stu.age) // 1111 18
console.log(person.name, person.age) // xxx 18

值得一提的是,现在 JS 已经提供一个 Object.create 方法实现上面代码中 createObject 方法的功能。

构造函数的寄生组合式继承

Student.prototype = Object.create(Person.prototype)
// 不会影响到 Person 的 prototype
Student.prototype.name = 'xxxx'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值