ES6箭头函数中的this和普通函数中的this

在普通函数中的this:

this的值是在执行的时候才能确认,定义的时候不能确认!为什么呢 —— 因为this是执行上下文环境的一部分,而执行上下文需要在代码执行之前确定,而不是定义的时候。

1、this总是代表它的直接调用者,比如:obj.fun,那么fun中的this是obj

2、如果没有直接调用者,默认情况下(非严格模式)this为window对象(举例:回调函数里的this如果没有做特殊处理,则指向window),严格模式中('use strict'),this为undefined

var obj = {
  aa:'obj___aa',
  b(fn){
    fn()
  }
}
function c(){
  console.log(this.aa)
}
var aa = 'window___aa'
obj.b(c)

//打印window___aa,obj.b回调里的this指向window

3、使用call、apply、bind硬绑定this。

因为使用call和apply硬绑定this,所以ES5 中提供了内置的方法 Function.prototype. bind,bind() 会返回一个新函数,它会把参数设置为 this 的上下文并调用原始函数。
function foo(something) {
  console.log( this.a, something );
  return this.a + something;
}
var obj = { a:2 };
var bar = foo.bind( obj );  //bind返回了一个新的函数,这个函数指定了this指向obj
var b = bar( 3 );  // 2 3

4、使用new 调用构造函数创建对象时this指向创建的新对象

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。
  1. 创建(或者说构造)一个全新的对象。
  2. 这个新对象会被执行 [[ 原型 ]] 连接。
  3. 这个新对象会绑定到函数调用的 this
  4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
总结:
当this绑定命中多个规则时,需要根据优先级判定this的绑定
  1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。var bar = new foo()
  2. 函数是否通过 callapply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是指定的对象。var bar = foo.call(obj2)
  3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上下文对象。var bar = obj1.foo()
  4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。var bar = foo()
TIP:
当call、apply、bind传入null或undefined时,使用默认绑定,即非严格模式下绑定到window
 

ES6中的this:

箭头函数不会使用以上四种规则,而是根据词法作用域来决定this,具体来说,箭头函数会继承外层函数调用的 this 绑定(无论this绑定是什么),即继承父级的this,这个父级是什么意思呢?

注意:this一旦被捕获,就不再发生变化,任何方法都改变不了其指向,如 call() , bind() , apply()

先来理解执行上下文,具体请看执行上下文和作用域

在JS中,调用函数时会创建一个“上下文对象”,调用函数内部的函数时,它与父级以及祖先级的上下文对象形成了执行上下文栈,而这个父级就是指箭头函数所在执行上下文栈上的上一个“上下文对象”,有点绕口,通过一个例子来说明:

TIPS:关于作用域请查看js之作用域和内存问题

var a=100;
var b = {
  a:1000,
  b:{
    a:1,
    c:{
      a:22,
      getA:()=>{
        console.log(this.a);
      }
    }	
  }
}

执行b.b.c.getA();

最后执行的结果是100,为什么呢,因为执行getA时,作用域链中的第一个对象是getA函数本身的上下文对象,上一层对象就是顶层的window对象的上下文对象,它的this是指向window的。

再来看一个例子:

var a=100;
var b = {
  a:1000,
  b:{
    a:1,
    c:{
      a:22,
      getA:()=>{
        console.log(this.a);
      }
    },	
    d:function(){
      return {
        getA:()=>{
          console.log(this.a);
        }
      }
    }
  }
}

执行b.b.d().getA();

最后结果为1。

此时的作用域链为getA -> d -> window,getA为箭头函数,因此它的this指向的就是作用域链中的d函数,而d函数中的this指向的是b.b对象,因此this.a就是b.b.a,所以结果为1

 

箭头函数与普通函数的区别详解

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值