你不知道的This和Class

  • Oh no....我的This又丢失了???
  • 为什么我用Class'实例化'出来的对象会相互影响??? ####这些问题都是因为JS的运行机制造成的。在JS中所有的一切都是对象,而this是对象的一个属性。在对象被调用时,this动态的根据上下文环境进行绑定,因此this和词法作用域没有关系。

一、何谓this

  1. this是函数执行上下文对象的一个属性,存在于运行时,而不是定义时,所以它和词法作用域没有必然的关系。
  2. 要使用this,首先需要考虑的是函数的调用环境而不是编写定义环境。它不指向函数本身,也不指向词法作用域。它由函数调用时发生在上下文环境的绑定而决定。
  3. 使用this要找函数的调用位置,而不是函数的声明位置。调用栈记录了函数的调用位置和顺序。通过调试工具可以查看调用栈,找出函数的调用位置。调用时使用了谁的上下文,this就指向谁。特别要注意的是回调函数传递的是引用,所以会丢失this。真正执行回调函数的位置决定了this的指向。
  4. bind把用来硬绑定函数执行的上下文,用于硬绑定this。(在React组件构造函数中显示的绑定This,防止丢失上下文环境)。除此之外,赋值表达式会传递函数的引用,它的调用位置会变成函数声明的位置。
  5. JS中Class对象的构造函数不是其它面向对象语言的构造函数,它是对已有函数的构造调用,本质上也是This的绑定。new关键字看上去像实例化对象,其实只是根据已有函数生成新的函数对象,并通过new关键字将this绑定到新创建的对象的调用上下文环境中。比如,var test =new foo(),用 new 来 调用 foo(..) 时,我们会构造一个新对象并把它绑定到foo(..) 调用中的 this 上。
  6. 箭头函数本身没有this,它在执行时会捕获调用所在词法作用域父函数的this。捕获绑定之后无法再次被修改。()=>的this是和词法作用域有关系的。而function定义的函数是和词法作用域没有关系的,只和调用环境有关系。http://stackoverflow.com/questions/35813344/do-es6-arrow-functions-still-close-over-this-even-if-they-dont-use-it
  7. this和JS中的Class可以关联使用,通过this的重新绑定可以实现混入 '父类'属相和方法的功能,也就实现了隐士的类似Class的伪多态。
根据下面这四条规则来判断this的绑定对象。
  1. 由 new 调用? 绑 定 到 新 创建 的 对象。
  2. 由 call 或者 apply( 或者 bind) 调用? 绑 定 到 指定 的 对象。
  3. 由上下文对象调用? 绑定到那个下文对象。
  4. 默认: 在严格模式下绑定到undefined,否则 绑 定 到 全局 对象。