你不知道的This和Class
发布时间:2016年10月27日
作者:
文章转自网络,版权归原作者所有,反馈可立刻删除
(该文来自笔记,点击查看原文)
-
Oh no....我的This又丢失了???
-
为什么我用Class'实例化'出来的对象会相互影响??? ####这些问题都是因为JS的运行机制造成的。在JS中所有的一切都是对象,而this是对象的一个属性。在对象被调用时,this动态的根据上下文环境进行绑定,因此this和词法作用域没有关系。
一、何谓this
-
this是函数执行上下文对象的一个属性,存在于运行时,而不是定义时,所以它和词法作用域没有必然的关系。
-
要使用this,首先需要考虑的是函数的调用环境而不是编写定义环境。它不指向函数本身,也不指向词法作用域。它由函数调用时发生在上下文环境的绑定而决定。
-
使用this要找函数的调用位置,而不是函数的声明位置。调用栈记录了函数的调用位置和顺序。通过调试工具可以查看调用栈,找出函数的调用位置。调用时使用了谁的上下文,this就指向谁。特别要注意的是回调函数传递的是引用,所以会丢失this。真正执行回调函数的位置决定了this的指向。
-
bind把用来硬绑定函数执行的上下文,用于硬绑定this。(在React组件构造函数中显示的绑定This,防止丢失上下文环境)。除此之外,赋值表达式会传递函数的引用,它的调用位置会变成函数声明的位置。
-
JS中Class对象的构造函数不是其它面向对象语言的构造函数,它是对已有函数的构造调用,本质上也是This的绑定。new关键字看上去像实例化对象,其实只是根据已有函数生成新的函数对象,并通过new关键字将this绑定到新创建的对象的调用上下文环境中。比如,var test =new foo(),用 new 来 调用 foo(..) 时,我们会构造一个新对象并把它绑定到foo(..) 调用中的 this 上。
-
箭头函数本身没有this,它在执行时会捕获调用所在词法作用域父函数的this。捕获绑定之后无法再次被修改。()=>的this是和词法作用域有关系的。而function定义的函数是和词法作用域没有关系的,只和调用环境有关系。http://stackoverflow.com/questions/35813344/do-es6-arrow-functions-still-close-over-this-even-if-they-dont-use-it
-
this和JS中的Class可以关联使用,通过this的重新绑定可以实现混入 '父类'属相和方法的功能,也就实现了隐士的类似Class的伪多态。
根据下面这四条规则来判断this的绑定对象。
-
由 new 调用? 绑 定 到 新 创建 的 对象。
-
由 call 或者 apply( 或者 bind) 调用? 绑 定 到 指定 的 对象。
-
由上下文对象调用? 绑定到那个下文对象。
-
默认: 在严格模式下绑定到undefined,否则 绑 定 到 全局 对象。