关于class中的函数问题
为什么在class中的普通函数会挂在className.prototype下面,而箭头函数是挂在类的实例下面。举个例子吧
class F {
handleX() {}
handleY = () => {}
}
typeof F.prototype.handleX === 'function' // true
typeof F.prototype.handleY === 'function' // false 主要疑问点???
let ff = new F
typeof ff.handleY // function
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为语法就是这样设计的呀,为啥要这样设计呢?TC39 的大佬们讨论出来的结果呀。
handleY 这个语法严格意义上还不是 ES 标准呢,现在还只是个处于 stage 3 的提案。https://github.com/tc39/proposal-class-fields 但 Babel 早就支持了所以大家用得都很欢快了,尤其是在 React 中。
这里的迷惑点是箭头函数和普通函数,其实不然啦。你所说的
普通函数
叫方法定义,这个是 ES6 class 中就有的,而箭头函数那个,这里的定义叫做字段定义
。你把箭头函数换成一个其他的值,然后尝试去理解,你看,它是不是看起来就和 handleX 毛关系都没有?其实这个等价于:
看起来还是很迷惑?为什么并列写一块儿,一个是在 prototype 上,另一个是在实例上? 这个提案其实吵了很久了,现在基本没有逆转的余地了。所以你就记住就好了,method 定义在 prototype 上,field 定义在实例上。而题目中的 handleY 赋值一个箭头函数它其实是 field 定义,所以不会在原型上啦。
其实输出你会发现这个 this 指向的是实例对象
而箭头函数内部的 this,记录的是词法环境下的 this,并不是运行时确定的,什么意思呢,就是当箭头函数声明时其内部的 this 值就已经确定了。一般情况下使用箭头函数时,按照声明时的环境,就可以知道其内部的 this 的值了,而且不能被改变的。而且你看输出是实例对象,表明其声明环境应该在实例化的过程中,其实这个是新语法,使用 =,而不是 : 号的,而类本质是是一个普通函数,你可以看看下面的例子
你是希望 this 指向实例化对象呢,还是指向外部的 this 呢,在严格模式下,如果是挂载在原型上 this 其实是 undefined,没有太多意义。可能你会想把实例化过程中去挂载原型,这样 this 也能指向实例对象,但是这种每次实例化都生成新的声明,就不用挂载到原型了,原型本来就是方便重用的。
你的上面代码可以通过 babel 的转码为
constructor 函数执行时的环境就是实例环境,这样箭头函数内部可以通过 this 访问实例对象,比用在原型更有实用价值。或者反过来想,如果这个是原型方法,但是 this 只是 undefined 或者是 window,那这个方法本质是没有意义的,可能你会说,可以不访问 this,那这个方法更应该放置的位置是静态方法