【JS】JS的原型链 - 继承的一种实现
ES5/ES6 的继承
- ES5的继承(原型链继承)中,子类和父类的
__proto__
都指向[Function]
- ES6的继承(类的
extends
),子类的__proto__
会指向父类,阮一峰
:
子类必须在
constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super
方法,子类就得不到this
对象。ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。
- class 声明会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量。
- class 声明内部会启用严格模式。
- class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
- class 的所有方法(包括静态方法和实例方法)都没有原型对象
prototype
,所以也没有[[construct]]
,不能使用new
来调用。 - 必须使用
new
调用 class。 - class 内部无法重写类名
总结
- 每创建一个函数,该函数都会自动带有一个
prototype
属性,这个属性是一个指针,指向一个对象,该对象称为原型对象。 - 原型对象上默认有一个属性为
constructor
,该属性也是一个指针,指向其相关联的构造函数。 - 通过调用构造函数产生的实例对象,都有一个内部属性,指向了原型对象,其实例对象能够访问原型对象上的所有属性和方法。
- 每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。
- 实例可以通过内部指针访问到原型对象,原型对象可以通过
constructor
找到构造函数。 functions
中有prototype
,objects
中有__proto__
,prototype
是函数才有的属性,__proto__
是每个对象都有的属性,但__proto__
不是一个规范属性,只是部分浏览器实现了此属性,对应的标准是[[Prototype]]
- 大多数情况下,
__proto__
可以理解为“构造器的原型”,即:__proto__===constructor.prototype
。 __proto__
的指向取决于对象创建时的实现方式。- 构造函数实例,封装的函数,如果通过
new
操作符来调用,就是构造函数,如果没有通过new
操作符来调用的,就是普通函数。 - 函数
Person
(对象)有一个属性prototype
指针,指向原型对象,Person.prototype
原型对象,实质也是对象,它有个属性constructor
指针,又指向Person
函数对象。 - 可以通过实例对象的
constructor
访问构造函数,可以使用代码person1.constructor
访问构造函数,但是constructor
的本质是原型对象上的属性。 - 所有对象都有
valueOf
和toString
方法的原因就是从Object.prototype
继承的。 - 在整个原型链上寻找某个属性,对性能有影响的,越是上层的原型对象,对性能的影响就越大,如果寻找某个不存在的属性,将会遍历整个原型链。
- js中一切都是对象,但是也区分普通对象和函数对象,通过
new Function()
出来的就是函数对象。普通对象的构造函数就是Object
,而函数对象的构造函数就是Function
。 Function prototype
是一个空函数。- 每个对象都有
__proto__
属性,但是只有函数对象才有prototype
属性。
以上是 【JS】JS的原型链 - 继承的一种实现 的全部内容, 来源链接: utcz.com/a/68541.html