# this指向

# 阅读下面代码,分析执行结果,并说明具体原因。

var num = 20;
const obj = {
  num: 10,
  func: num => {
    this.num += 5;
    console.log(this.num);

    num += 5;
    console.log(num);
    var num = 30;

    return function () {
      this.num += 4;
      console.log(this.num);

      num += 10;
      console.log(num);
    };
  },
};
obj.func(40)();

# 答案

  1. 浏览器环境中输出:25,45,29,40
  2. node环境中输出: NaN 45 NaN 40

# 解析

  1. 在浏览器环境中

obj.func它是一个箭头函数,箭头函数的this要看当前执行环境的上下文来决定,当前执行环境是windowthis的指向必然是全局对象也就是window,所以里面的this.num就是window下的num,所以结果是25.
obj.func执行的时候,带入了实参num=40函数内的var num虽然有变量提升,但是提升的只是声明,在它声明之前,形参内已经声明过了num,所以这个声明就不会生效,那num的值就是实参传过来的40,所以打印出的num45.
obj.func执行后的返回值是个匿名函数,这个函数内的this跟它的执行体有关,这个函数的执行体依然是window, 所以里面的this.num还是window下的num,由于window下的num在之前被执行过加法运算,此时获取到的num值是25, 因此此时在执行加法运算结果就是29.
obj.func的返回值匿名函数内没有声明变量num,所以向它的父级作用域查找,此时父级作用域下的num被赋值为30,所以打印结果是40.

  1. 在node环境中

全局环境中this指向的是一个空对象{}.
obj.func函数在执行的时候,因为它是箭头函数,this指向{},没有num属性,因此运算时为undefined + 5结果是NaN.
obj.func在执行的时候,带入了实参num=40函数内的var num虽然有变量提升,但是提升的只是声明,在它声明之前,形参内已经声明过了num,所以这个声明就不会生效,那num的值是实参传过来的40,所以打印出的num45.
obj.func执行后的返回值是个匿名函数,这个函数内的 this 跟它的执行体有关,这个函数内的this依然是{}, 所以里面的this.num还是不存在的,打印结果是NaN.
obj.func的返回值匿名函数内没有声明变量num,所以向它的父级作用域查找,此时父级作用域下的num被赋值为30,所以打印结果是40.

Last Updated: 5/18/2021, 4:46:06 PM