原文地址
笔记而已,欢迎指正
原型链
一、整体梳理
-
__proto__
是实例所独有的,正常情况下指向其构造函数的 prototype -
prototype
是函数独有的,函数声明后自带 prototype 对象 -
constructor
是 prototype 对象独有的,指向构造函数 -
函数是 Function 的实例也是对象,所以函数同时拥有
__proto__
、constructor -
ES6 中
__proto__
可用 Object.getPrototypeOf 和 Object.getPrototypeOf 来操作
二、Function
Function 较为特殊
typeof Function.prototype // "function"
Function.prototype instanceof Function // false
Function.prototype instanceof Object // true
-
最简单的说法是 Function.prototype 类型是函数,是为了兼容之前版本的 EcmaScript
-
Function.prototype 本身是一个对象,是 Object 的实例,只是内部实现了
[[Call]]
属性变得可以执行,返回 undefined
三、Object
- Object 是函数,所以是 Function 的实例
Object.__proto__ === Function.prototype // true
-
Object.prototype 是个对象,但它的
__proto__
为 null(原型链终点) -
普通函数是 Function 的实例,其 prototype 是 Object 的实例
function Foo() {}
Foo.__proto__ === Function.prototype // true
Foo.prototype.__proto__ === Object.prototype // true
继承
一、Class 的继承实现
拥有两条继承链
- 子类 prototype 原型指向父类 prototype,用于继承原型上的属性和方法
class Parent {}
class Child extends Parent {}
Child.prototype.__proto__ === Parent.prototype // true
- 子类原型指向父类,用于继承静态属性和方法
Child.__proto__ === Parent // true
- 内部实现时,子类构造函数中调用父类,用于继承实例属性和方法
function Child() {
Parent.call(this)
}
二、Babel polyfill
可自行在 babel 官网编译
class Parent {
constructor() {
this.setup()
}
static level = 'parent'
setup = () => {
console.log("parent")
}
}
class Child extends Parent {
id = 61
setup = () => {
console.log("child")
}
getId() {
console.log("child getId")
return id
}
}
new Child()
-
函数属性
setup
(或称函数表达式)被当做了普通属性,通过 defineProperty 实现 -
函数声明
getId
则是挂在了 prototype 上 -
另外属性赋值是在构造函数中完成,函数声明则是通过「继承闭包」与构造函数分开,再挂到 prototype
-
上一点对 JS 的继承会有影响,由打印可见,
setup
最终还是执行 parent 上的函数,就是因为 Child 在Parent.call(this)
时,就已经把函数属性挂上去了 -
虽然函数属性书写时绑定 this 方便,但在继承时需要额外注意
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!