IT大道IT大道

首页 >  技术 > es6中类和extends的本质

es6中类和extends的本质

原文 http://blog.csdn.net/theanarkh/article/details/54355425 2017-01-11 23:41:45 0 评论

理解es6的类和extends的原理,主要是先理解es5里面函数和对象间的关系(_ proto _和prototype的知识)

class c {
    constructor(){}
    //static f() {}
    a() {}
}
class d extends c{}
通过typeof打印我们知道,c和d本质其实还是一个函数.接下来我们看最开始的地方c.prototype。![这里写图片描述](http://img.blog.csdn.net/20170111230647258?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEhFQU5BUktI/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
从图中我们可以看出,我们在class c里面定义的东西其实都是定义在c的prototype里的,然后我们再看一下d.__proto__。![这里写图片描述](http://img.blog.csdn.net/20170111231832108?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEhFQU5BUktI/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![这里写图片描述](http://img.blog.csdn.net/20170111231848504?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEhFQU5BUktI/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
从图中我们可以知道,d的原型__proto__是等于函数c的,继续,我们看看d的prototype属性![这里写图片描述](http://img.blog.csdn.net/20170111232235916?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEhFQU5BUktI/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![这里写图片描述](http://img.blog.csdn.net/20170111232254604?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEhFQU5BUktI/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
从图中我们可以看到d的prototype指向一个c生成的对象。并且我们可以通过打印看到虽然d.prototype指向了c,但是d.pototype.constructor === d是返回true的,这应该是js引擎做了修改,这也和我们平时实现继承时的做法一样。所以es6的继承其实是基于es5的方法的,只是写法变了,语法是为了方便我们写代码,最后由js做转化,但是也加了一些特性。首先有一个地方就是把d.__proto__指向了c本身,这里有什么用呢,es5的时候d.__proto__是指向一个function(){}这样的匿名函数。我们平时使用的call和apply就是存在这个匿名函数里的。es6这个做法我觉得应该是为了支持static这个语法。在class c里面定义一个静态的函数f,他的子类d也可以通过d.f去访问,我们把刚开始的那段代码里的注释去掉,通过打印我们可以知道Object.prototype.hasOwnProperty.call(c,'f')//true
Object.prototype.hasOwnProperty.call(d,'f')//false
d.f访问的f其实是源于他的父类c的,这就是d.__proto__ = c的作用。最后还有一个地方是,在c里可以定义getter和setter,比如get a(){},这些和es5里都是一样的,这些属性都会被挂在到c.prototype里面去。

Tags:javascript  

标签列表