关于javascript:关于箭头函数里的this

9次阅读

共计 2933 个字符,预计需要花费 8 分钟才能阅读完成。

对于箭头函数里的 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 的 this
obj.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 的 this

obj.fun1()()()(); //

总结

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

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

正文完
 0