JavaScript 的继承是通过原型链实现的,要实现继承需要理解原型和原型链的概念。
原型和原型链
1、仅函数上存在 prototype 属性(这是一个显式原型属性),其指向原型对象,原型对象上存在两个属性:constructor 和 [[prototype]] (无法访问,部分浏览器可通过 __proto__
访问,这是一个隐式的原型属性)
- constructor :指向构造函数,即是函数自身
- [[prototype]](
__proto__
):指向构造函数的原型对象,即 Object ,Object.__proto__ = null
2、当通过 new 调用这个函数时,得到的对象会存在 [[prototype]](__proto__
),指向的是函数的 prototype 属性
3、所有的对象上都存在 [[prototype]](__proto__
)属性
4、这种通过 __proto__
在各对象间建立链接的工具就是原型链,通过原型链可以访问到其他对象的属性和方法
继承的实现方式
继承指一个对象直接使用另一对象的属性和方法。JavaScript 的继承是通过原型链实现的。
实现属性继承的核心代码是:
SuperFn.call(this)
实现方法继承的核心代码是:
SubFn.prototype.__proto__ = SuperFn.prototype
具体实现方式有以下6种:
1、ES6 class类 extends 继承
通过ES6 新增的语法糖实现继承
2、基于原型继承
原型赋值SubFn.prototype = new SuperFn();
问题点:
- 原型对象的 constructor 属性值变为 Object
- 原型对象中包含引用值,值操作会同时反应到所有继承对象上
-
子类型在实例化时不能给父类型的构造函数传参
3、借用构造函数
构造函数内部执行 SuperFn.call(this)
,只能继承属性,不能继承原型链上的方法
问题点:
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 字类构造函数无法实现复用,每个子类都有父类实例函数的副本
4、组合继承
构造函数内部执行 SuperFn.call(this)
,原型赋值 SubFn.prototype.__proto__ = SuperFn.prototype;
5、原型式继承
此种方式和 subObj = Object.create(superObj)
实现的功能相同
6、寄生式组合继承
构造函数内部执行 SuperFn.call(this)
,原型赋值 SubFn.prototype = Object.create(SuperFn.prototype);
原文始发于微信公众号(蓝桥云课精选):JavaScript 基础知识总结:继承
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论