js对象方法里面为什么不能用箭头函数

先上个代码例子,再说我不理解的地方,求指点,谢谢!

var name="window";
var obj={
  name:'netease',
   print1:()=>{
    console.log(this.name);
  
  }
}
obj.print1();//window

es6中的this是定义时绑定,跟运行时无关,我很纳闷就是这个例子中,定义时 print1方法里面的this不是应该最先查找到的就是obj里面的name吗,为什么输出是window,还是绑定到全局变量上去了?不是明明print1里面没有this,再查找外围this,先找到的应该是obj中的this吗?

阅读 9.3k
8 个回答

谢邀。

下面这句话引自《深入理解ES6》

箭头函数没有 this/super/arguments/new.target 的绑定,这些值是由外围最近一层非箭头函数决定。

箭头函数的this和普通函数的this可以看成完全两个概念的东西,不用传统的this去理解。

我对外围的理解是,这个外围指的是()=>{}整体的外围,比如你的代码中:name属性的外围是什么?print1的外围是什么?。所以 ()=>{console.log(this.name);}的外围已经出了obj,从而进入window

可以借助我下面的代码来理解:

    var name = "window";
    var obj = {
        name: 'netease',
        print1: () => {
            console.log(this.name);
        },
        print3: function () {
            return ()=>{
                console.log(this.name);
            }
        }
    }
    obj.print1();// window
    obj.print3()();// netease 注意是返回闭包函数
  1. 箭头函数的this完全根据外部作用域来决定
  2. 全局下的对象当前的this是window。

解决方案:

var name="window";
var obj= {
    name : 'netease',
    that : this,
    print1: function(){     //函数包裹
        return ()=>{
            console.log(this.name);
        }
    },
    print2: ()=>{
        console.log(this.name);
    }
}
console.log(obj.that);     // window
obj.print1()();            // netease
obj.print2();              // window
  1. 我们先要搞清楚一点,obj的当前作用域是window,如 obj.that === window。
  2. 如果不用function(function有自己的函数作用域)将其包裹起来,那么默认绑定的父级作用域就是window。
  3. 用function包裹的目的就是将箭头函数绑定到当前的对象上。 匿名函数的作用域是当前这个对象,所以之后箭头函数会自动绑定到此函数所在作用域的this,即obj 。

我最近的文章里有详细的说明。 ( 逃

箭头函数是本身没有执行的上下文,没有本身的this 是找离他最近的一个执行环境作为执行上下文,最近的this作为它的this 在这里,是window
可以试试以下代码 把var name="window"去掉

var obj={
  name:'netease',
   print1:()=>{
    console.log(this.name);  
  }
}
obj.print1();//结果是undifined

再试试以下代码
  var obj={
  name:'netease',
   print1:function(){//不用箭头函数,this指向obj对象本身

    console.log(this.name);  
  }
}
obj.print1();//结果是netease

es6,箭头函数的this指向父级

其实很容易看的。

普通函数的 this 是动态的,所以要在运行时找拥有当前上下文的对象。

而箭头函数的 this 是静态的,也就是说,只需要看箭头函数在什么函数作用域下声明的,那么这个 this 就会绑定到这个函数的上下文中。即“穿透”箭头函数。

例子里的箭头函数并没有在哪个函数里声明,所以 this 会 fallback 到全局/undefined

https://blog.crimx.com/2016/0...

箭头函数对this的绑定是强制性,优先级最高的而且不可更改的,简单理解就是直接使用了词法作用域,按照词法作用域来理解就不会出错,不用再理会那些复杂的this规则。
你的例子里的this就相对于指向了当前函数所在的词法作用域,也就是全局作用域,自然就是window。
如果不知道什么是词法作用域的话,换句话说,你直接写下面这样,效果也是一样的。

var name="window";
var obj={
  name:'netease',
   print1:()=>{
    console.log(name);
  
  }
}
obj.print1();

箭头函数没有自己的上下文,this为调用方法时所在上下文
如图,这里就是在window下调用,上下文为外面的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题