读《You-Don't-Know-JS》遇this绑定疑问:代码输出1的call-site是什么?
理解这段代码里的this和call-site
嘿,我当初啃《You-Don't-Know-JS》的时候,也在this的绑定规则上绕得晕头转向,太懂你这种疑惑了!咱们一步步拆解你的问题:
首先,先明确你提到的call-site(调用位置):就是函数被实际调用的那一行代码,不是它被定义的地方。在你的代码里,b()的call-site就是a()函数内部的b();这一行。
先把你的代码贴出来方便分析:
function a() { function b() { console.log(this.myVar); } var myVar = 2; b(); // 这就是b的call-site } var myVar = 1; a(); // 输出1
接下来用this的默认绑定规则拆解:
- 当一个函数以普通函数调用的方式执行时(既不是作为对象的方法调用,也没用
call/apply/bind,也不是new调用),this会默认绑定到全局对象(浏览器环境是window,Node.js环境是globalThis)。 - 在你的代码里,
b()就是标准的普通函数调用,所以b内部的this指向全局对象。 - 全局对象上的
myVar是你最外层声明的var myVar = 1,所以console.log(this.myVar)自然输出1。
你可能会疑惑:为什么不是a函数里的myVar = 2?因为a里的myVar是局部变量,它并没有挂在任何对象上,和this完全不沾边。b的this绑定到全局,只会去全局对象上找myVar属性,不会去a的作用域里找普通变量。
如果想让b输出2,你可以改成把myVar挂在a的this上,或者用闭包,或者用call手动绑定:
比如这样:
function a() { function b() { console.log(this.myVar); } this.myVar = 2; // 把myVar挂到a的this上 b.call(this); // 手动把b的this绑定到a的this } var myVar = 1; a(); // 输出2
这样是不是就清晰多啦?this的核心真的就是“谁调用我,我就指向谁”,而调用的方式直接决定了绑定规则~
内容的提问来源于stack exchange,提问作者SuicideSheep
相关产品推荐
相关产品推荐

