阴影“这个” - 词汇名称解析

Shadowing `this` - lexical name resolution

本文关键字:词汇 这个 阴影      更新时间:2023-09-26

编辑:我认为这不是重复的;它是一个隐藏的参数,我想问一下与this相关的阴影,以及词汇范围,阅读了这个SO Q/A re.阴影。

我曾认为名称的含义this可以动态解决(在范围方面),以便解释为什么在我看来它没有通过词法解决:

function foo() {return this;}
var a = {f: foo};
var b = {f: foo};
a.f() !== b.f();
a.f() !== foo();
a.f() !== window; //not strict mode

但后来我读到每个函数都静默地接收this作为附加参数。(我意识到箭头功能是不同的。

显然helper()并不像我们希望的那样有效:

ob = {
  meth: function(){
    var helper = function() {return this;};
    return helper();
  }
};
ob.meth(); //Window or undefined

据我了解,解释器不是通过查看封闭范围来解决this(结果是ob),而是调用helper()this设置为 undefined(严格模式),静默地作为参数传递。

那么,周围范围的this是否有效地被遮蔽了,因此词汇范围实际上是在起作用的?

你是对的。除箭头函数的情况外,this永远不会通过词法解析。它始终指以下之一:

  1. 调用函数的对象,例如valueOfThis.foo()
  2. 第一个参数applycall,如foo.apply(valueOfThis, params)foo.call(valueOfThis, ...)
  3. DOM 元素,如果是事件处理程序,例如 <button onclick="alert(this.tagName.toLowerCase());"/>
  4. 当函数用作构造函数时正在构造的对象,例如Foo = function(){ ... }; new Foo()
  5. 绑定到函数的对象(如果函数是使用 bind 创建的,例如 bar = function(){ ... this ...}; foo = bar.bind(valueOfThis); foo()
  6. 在 getter/setter 中,this 是指正在为其访问或设置属性的对象,例如valueOfThis.someProperty = 123
  7. window(通常)如果以上情况都不是,例如foo()

@Bergi下面的评论中为所有这些提供了很好的参考。

对于绑定函数,被调用的函数实际上与传递给 bind 方法的函数不同,因为 bind 方法创建一个新函数

那么,周围的范围是否有效地被遮蔽了,因此词汇范围实际上是在起作用的?

是的,人们可以从这个角度看待它。绑定到helper作用域的this将隐藏到meth作用域的。(如果你使用过箭头函数,它就不会)。

但是,您仍然需要记住,this不是一个普通变量,而是一个特殊的关键字。它只绑定到函数作用域,它不可写,它在草率模式下具有奇怪的强制对象语义,并且它总是隐式绑定 - 正如你所说,一个隐藏的参数。

除非你试图理解this在箭头函数中是如何工作的(以及它们的词法分辨率),否则与范围和阴影的类比是毫无用处的。