对于箭头函数里的this

先说总结:

  • 箭头函数没有本人的this、arguments,箭头函数里的this用的是parent作用域的this
  • 箭头函数里的this是词法作用域,是由代码构造决定的,跟在哪里调用无关,与箭头函数在代码里的地位无关
  • 确定箭头函数里this的指向,能够动态剖析代码构造,始终往上找function,如果有,就是最近的function里的this,如果到最外层都没有,就是window
  • 箭头函数的this,一旦确定后是不可更改的

记住,箭头函数里的this是能够动态剖析的,然而函数里的this又齐全不一样了


上面开始注释

箭头函数没有本人的this、arguments,箭头函数里的this用的是parent作用域的this

廖雪峰的文章说,箭头函数里的this是词法作用域

那么就是由代码构造决定的,跟在哪里调用无关,事实证明也是这样的。

箭头函数呈现的地位有两种:

  • 在对象里
  • 在函数里
箭头函数在对象里
var obj = {    param: 123,    ff : () => console.log(this), // window, strict模式下是undefined}

因为箭头函数没有本人的this,会去找parent的this,然而对象不形成独自的作用域,没有词法作用域,所以持续往上找parent,就找到了全局作用域。

通过babel编译,发现间接就把this替换成了undefined

// bebal编译后的后果// void 0就是undefined"use strict";var _this = void 0;var obj = {  param: 123,  ff: function ff() {    return console.log(_this);  } };
箭头函数在函数里
function test () {    let param = 5656;    let ff = () => console.log(this);}

箭头函数的this是词法作用域,词法作用域是跟代码构造相干的,那么是能够动态剖析的。

因为是词法作用域,那么箭头函数里的this跟在哪里调用无关,与箭头函数在代码里的地位无关

咱们剖析一下,箭头函数没有本人的this,会找parent的this,它的parent的是test函数,函数是有作用域的,有词法作用域,所以test里的this就是箭头函数的this。

也就是箭头函数里的this,通过动态剖析,会始终往上找function,找到了,就用最近的function里的this,找不到,就用window

通过babel编译一下,发现箭头函数的this即是test函数里的this:

"use strict";function test() {  var _this = this;  var param = 5656;  var ff = function ff() {    return console.log(_this); // 这里的this取的是test函数的this  };}

因为箭头函数和test函数的this是一样的,那么如果test函数里的this变动了,那么箭头函数的this也会跟着变动。比方看这个例子:

let obj = {  param: 123,  ff: function () {   let rr = () => console.log(this);   rr();  }}obj.ff(); // obj , 因为这时ff函数里的this是obj对象let tt = obj.ff;tt();  // window ,因为这时ff函数里的this是全局对象

这个通过babel编译后的后果是:

"use strict";var obj = {  param: 123,  ff: function ff() {    var _this = this;    var rr = function rr() {      return console.log(_this);    };    rr();  }};obj.ff();var tt = obj.ff;tt();
留神,箭头函数的this,一旦确定后是不可更改的

这句的了解是:箭头函数的this一旦确定,就不能更改了,典型的如在setTimeout函数里用箭头函数。要辨别下面的状况,箭头函数rr的this取的是ff函数的this,然而ff函数的this是没有确定的,运行起来后ff函数的this才确定。

function test () {    return () => console.log(this);}let obj = {    aa: 123,}let rr = test.call(obj);setTimeout(rr,1000); // obj ,而不是window   因为箭头函数rr的this曾经确定了,前面不能更改

多层嵌套的状况

let obj = {    ff1: function () {        let obj2 = {            ff2:  () => console.log(this),            obj3: new Object(() => console.log(this))        };        return obj2;    },    fun1: function (){         return function fun2(){            return function fun3(){               return ()  => console.log(this);            }        }    }}obj.ff1().ff2(); // obj, 取的ff1的thisobj.fun1()()()(); // window,取的fun3的this,因为嵌套函数的this不能继承,所以是window

箭头函数ff2里的this,向上找parent,obj2是对象没有作用域,持续向上,找到ff1函数,于是箭头函数ff2的this就是取ff1函数的this。obj3的new Object()的传参是箭头函数,外面的this实用的规定也一样,也是始终向上找parent,最初是ff1函数的this,看babel的转换的代码就晓得了。

"use strict";var obj = {  ff1: function ff1() {    var _this = this;    var obj2 = {      ff2: function ff2() {        return console.log(_this);      },      obj3: new Object(function () {        return console.log(_this); // 取的是ff1的this      })    };    return obj2;  },  fun1: function fun1() {    return function fun2() {      return function fun3() {        var _this2 = this;        return function () {          return console.log(_this2);        };      };    };  }};obj.ff1().ff2(); // obj, 取的ff1的thisobj.fun1()()()(); //

总结

  • 箭头函数没有本人的this、arguments,箭头函数里的this用的是parent作用域的this
  • 箭头函数里的this是词法作用域,是由代码构造决定的,跟在哪里调用无关,与箭头函数在代码里的地位无关
  • 确定箭头函数里this的指向,是动态剖析代码构造,始终往上找function,如果有,就是最近的function里的this,如果到最外层都没有,就是window
  • 箭头函数的this,一旦确定后是不可更改的

记住,箭头函数里的this是能够动态剖析的,然而函数里的this又齐全不一样了