原型链继承与es6继承的区别

文章目录


开始之前,我们需要先知道:

  • 每个对象都有一个__proto__内部属性指向它的构造函数的原型对象,每个函数都有一个prototype属性指向它的原型对象。而每一个函数都是对象,所以一个函数既有__proto__内部属性,又有prototype属性。
  • 每一个实例,都有一个内部属性__proto__指向它的构造函数的原型对象

还需要再说一下。__proto__与prototype是不一样的。区别如下

- __proto__ prototype
存在性 __proto__是每个对象都有的(包括函数) 只有函数才有
含义 __proto__是指向它的构造函数的原型对象 指向函数的原型对象

?
上面可能有些不好理解

解释

现在开始啦!

/*用es6的extends实现的继承*/
class Point1 {
}
class ColorPoint1 extends Point1 {
}

/*用es5中原型链实现的继承*/
function Point2(){
}
let p=new Point2();
function ColorPoint2(){}
ColorPoint2.prototype=p;

在es5中,基础是通过修改子类构造方法的原型对象实现的,也就是ColorPoint2.prototype=p,而在es6中,直接用extends就行了。下面看一下区别。

ColorPoint1.__proto__ === Point1
//true
ColorPoint2.__proto__===Point2
//false
ColorPoint1.prototype.__proto__ === Point1.prototype
//true
ColorPoint2.prototype.__proto__ === Point2.prototype
//true

区别从上面代码中可以看出。就是ColorPoint2.proto===Point2ColorPoint2.prototype.proto === Point2.prototype的区别。

这是为什么呢?是因为es6类的继承是用下面方式实现的。

class A {
}

class B {
}

// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);

// B 继承 A 的静态属性
Object.setPrototypeOf(B, A);

const b = new B();

注意,setPrototypeOf设置一个对象内部属性__proto__为另外一个对象。如Object.setPrototypeOf(B, A)就是设置B.__proto__ = A。

接下来,我们看一下es6中继承的原型链图,如图1所示。
在这里插入图片描述

图1 es6的继承示意图

图中,蓝线就是Object.setPrototypeOf(ColorPoint1, Point1)

而es5中,用原型链实现的继承的示意图如图2所示。
在这里插入图片描述

图2 es5原型链实现继承的示意图

在es5用原型链实现继承的示意图中,子类构造函数的__proto__是没有进行处理的,还是指向了Object.__proto__。

总结

es6使用extends实现继承与es5使用原型链实现继承区别在于,es6设置了构造函数的继承,也就是子类构造函数的proto为父类构造函数。具体代码就是下面。

// ColorPoint1.prototype的proto继承Point1.prototype
Object.setPrototypeOf(ColorPoint1.prototype, Point1.prototype);
// ColorPoint1的proto继承point。
Object.setPrototypeOf(ColorPoint1, Point1);

参考文献

Class 的继承
所有javascript对象都有prototype还是仅仅函数对象有prototype?

发布了231 篇原创文章 · 获赞 93 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/wobushixiaobailian/article/details/100702392