你如何获得函数的"this"?

How do you get the "this" of a function?

如何从函数外部获取函数的 this 值,而不必调用它?例如,以下内容不起作用,但说明了这个想法:

// window is this, currently
function foo() {}
console.log(foo.this) // would log the window object.

Function.bind() 的 MDN 文档报告说 bind() "creates a new function that, when called, has its this keyword set to the provided value"。这意味着每个函数从一开始就有一个与之关联的 "this"。

问题是 "this" 是否可以从函数调用外部访问,因为根据 MDN 文档推测它的 "this" 引用已经存在。

在您的控制台中试试这个:

var foo = function() {}
var bar = foo.bind(this)
console.log(foo === bar)

结果是 false,这意味着您现在有两个函数,而不是一个,每个函数都有自己的 this

有人说"callsite"决定函数的this,这好像不对。如果你运行

var obj = {}
function foo() {
  console.log(this)
}
function Obj(func) {
  console.log(this)
  func()
}
new Obj(foo)

然后 foo 的调用站点在 new Obj 中,但它仍然记录 Window 对象。

如果你运行

var obj = {}
function foo() {
  console.log(this)
}
foo()
foo.call(obj)
foo.bind(obj)
foo()

然后你会注意到原来的 foo 函数的 this 没有改变。基于这个事实,以及 bindcallapply 的 MDN 文档,我们可以自信地假设函数的 this 永远不会改变。

this 可以根据您调用函数的方式进行更改,因此,没有真正的方法可以在函数之外获取它。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

您需要函数的一点帮助。

function foo(){
    return this;
};
console.log(foo());

不,没有办法获取this的值,因为this实际上与函数对象无关,而是与执行上下文相关调用函数时创建。

execution context 具有以下属性:

LexicalEnvironment
Identifies the Lexical Environment used to resolve identifier references made by code within this execution context.

VariableEnvironment
Identifies the Lexical Environment whose environment record holds bindings created by VariableStatements and FunctionDeclarations within this execution context.

ThisBinding
The value associated with the this keyword within ECMAScript code associated with this execution context.

现在,当函数被调用时the following steps take place:

10.4.3 Entering Function Code
The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
  3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
  4. Else set the ThisBinding to thisArg.
  5. Let localEnv be the result of calling NewDeclarativeEnvironment passing the value of the [[Scope]] internal property of F as the argument.
  6. Set the LexicalEnvironment to localEnv.
  7. Set the VariableEnvironment to localEnv.
  8. Let code be the value of F’s [[Code]] internal property.
  9. Perform Declaration Binding Instantiation using the function code code and argumentList as described in 10.5.

特别注意

[...] a caller provided thisArg [...]

这应该表明 this 的值是由函数的 调用者提供的

示例:

当一个函数被调用为foo()时,就没有thisArg,所以是undefined。在这种情况下,将执行第 2 步并且 this 绑定到全局对象。

但是,如果一个函数被调用为 foo.call(bar),那么 thisArg 就是 bar 并且会发生第 3 步或第 4 步,这取决于 bar 是否是一个对象与否。

我希望这能解释为什么无法获得函数的 this 值。