关于this的又一个问题

本人正在看《你不知道的javascript上卷》,第80页其有关使用this来隐式引用函数的词法作用域错误代码如下:

function foo(){
  var a = 2;
  this.bar();    //1
}
function bar(){
  console.log(this.a);
}
foo();

我在VS Code上将代码注释1处的this给删掉之后(如书中所说)发现尽管代码没有出错但是结果为undefined。在单步调试查看调用堆栈时是foo->bar,也就是按照我所想的bar()中this绑定到了foo函数对象上。
图片描述

百思不得其解之后在全局和bar函数中都另外再定义了不同值的a变量,然而结果还是undefined。。。突然想到是不是因为自动使用严格模式的原因,然而在各个浏览器控制台上测试同样是undefined的结果,无解。。。。。求助!!这个this到底绑定到哪里了!!

阅读 2.7k
7 个回答

this的作用域和它运行的环境有关,它指向调用某方法、对象的对象。比如这里,如果是node.js,就会一直指向global;如果是浏览器,就会一直指向window。不过node.js环境下,在最外面一层以var a = 1形式声明的变量,并不会绑定在node.js 的global上,以a = 1类似的方式声明。

如果去掉了 foo() 中 bar() 前面的 this,bar 的调用堆栈确实是 foo->bar,也就是说 bar 的调用位置在 foo 中。但是你有一个误解,「调用位置决定了 this 的绑定」并不是说只要找到调用位置就可以判断 this 的绑定了。
找到调用位置是判断 this 绑定的第一步,第二步要在调用位置运用 this 绑定的规则判断此时 this 属于哪种绑定,进而找到 this 的绑定对象。这一点在《你不知道的 js》第 83 页下方有明确讲解。

在这段代码中,我们找到了 bar 的调用位置,然后发现它是一个普通的函数调用,不是对象方法引用也没有使用绑定函数。所以 this 会应用默认绑定(《你不知道的 js》第 83 与 84 页),也就是 this 绑定到全局对象,而全局对象中没有 a 这个属性。根据词法作用域在非严格模式下的查找规则,这会返回一个值为 undefined 的 a。

浏览器里面普通函数调用,this是window,node里面是global,全局环境的this浏览器还是window,node是module.exports this是谁只取决于函数怎么调用的

  1. 在这个例子里,想在bar里面访问foo作用域中的变量是不可能的
  2. 在浏览器中,bar中的this指向全局变量。在node中不是

this是全局的window对象,a在你的foo方法里,是局部变量。所以是未定义。你可以看看这个,js this的四种场景

新手上路,请多包涵

bar中的thsi.a是没有的啊

推荐问题
宣传栏