关于es6里,prototype与__proto__
'use strict';
class A {
}
class B extends A {
}
console.log(B.__proto__ === A); // true 第1行
console.log(B.prototype.__proto__ === A.prototype); // true 第2行
console.log(A.__proto__ === Function.prototype); // true 第3行
console.log(A.prototype.__proto__ === Object.prototype); // true 第4行
疑问:【第3,4行】是es5的知识点,没啥疑问的。但【第1行】我始终不明白,为什么B.proto === A ??? 将B看作Function类的一个实例,那么B继承A,不应该也是等于A.prototype么 难道是es6中的extends关键字的效果么?
2 回复
mark
是的,es6中的extends实现继承的关键代码如下:
function _inherits(subClass, superClass) {
if (typeof superClass !== 'function' && superClass !== null) {
throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass)
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; // 这里
}
最后一行会使用ES6新特性的Object.setPrototypeOf
或一则polyfill将subClass
的__proto__
设置为superClass
的prototype
,的确是es6中extends关键字效果。
一般来说,继承这样来做:
B继承A
B.prototype = {
constructor: B,
__proto__: A.prototype
}
但是这样做的问题是对OOP的模拟不彻底:A的“静态成员”B是无法“继承”下来的,所以有两种做法:
- 使用
mixin
将A的"静态成员"混入B中,比如使用Object.assign
简单复制下引用; B.__proto__
直接引用A.prototype
,即Object.setPrototypeOf(B, A)
;
js仅仅是使用原型的引用传递来模拟OOP,如果非得通过B.__proto__ === Function.prototype
就把B看作Function类的一个实例来思考是肯定行不通的