在Javascript中是否有相当于.apply不改变这个值?
看起来很简单,我想用参数数组来调用一个函数。 当然,我可以说func.apply(this, ['some', 'arguments']);
但是这会改变this
func
的价值。 任何想法如何做到这一点而不改变它?
你不能, 因为this
在JavaScript中的工作方式 。 阅读:
通过ECMAScript规范的“input执行上下文”部分:当您调用一个函数时,其值由左边的内容决定(称为激活对象 )。 我们来创build一个叫做史蒂夫的函数,并把它放在一个对象中:
function steve(){} var obj = { method: steve };
…当我们把obj.method()
称为steve时,他的this
是obj
,因为obj
是激活对象。
棘手的情况是什么都不是在函数调用的左边:
steve(); // Who am I ?!
在函数调用的左边没有任何东西 – 实际上它是null
,所以它的值被设置为全局对象(web浏览器中的window
,Node.js中的global
等)的默认值。
所以你实际上每次调用它时都要设置一个函数。
PS调用steve.apply(null, [])
相当于调用steve()
。
请注意,在ES6中,你也可以写:
func(...someArray)
这里成为func
Window
,这是没有用的。 但是,如果你写:
obj.func(...someArray)
this
在里面的func
将是obj
。
这可能是我5年前寻找的function,但那是5年前,所以谁记得:)
当调用一个函数时, this
值并不神秘,这取决于它是如何被调用的“正常”(没有call
或apply
):
func(); // `this` is the global object, or undefined in ES5 strict mode obj.func(); // `this` is `obj`
所以为了避免“改变”这个值,只要传递正确的值来apply
,取决于你如何称之为“正常”:
func.apply(undefined, []); // global object, or undefined in ES5 strict mode obj.func.apply(obj, []);
如果您只是调用一个函数,则传递null
。
func.apply(null, ['some', 'arguments']);
如果您正在调用作为对象方法的函数,请传递该对象。
var arr = []; arr.push.apply(arr, ['some', 'arguments']);
为了匹配这是如何工作的。
你想要什么没有什么意义。
在ecmascript标准中this
是这样定义的:
11.1.1这个关键字this关键字评估当前执行上下文的ThisBinding的值。
函数执行上下文的thisBinding分辨率是这样指定的:
10.4.3input函数代码当控制进入函数对象F中包含的函数代码的执行上下文时,执行以下步骤,调用者提供了thisArg,调用者提供argumentsList:
- 如果函数代码是严格代码,则将ThisBinding设置为thisArg。
- 否则,如果thisArg为null或未定义,请将ThisBinding设置为全局对象。
- 否则,如果Type(thisArg)不是Object,则将ThisBinding设置为ToObject(thisArg)。
- 否则将ThisBinding设置为thisArg。
- 让localEnv是调用NewDeclarativeEnvironment传递F的[[Scope]]内部属性的值作为参数的结果。
- 将LexicalEnvironment设置为localEnv。
- 将VariableEnvironment设置为localEnv。
- 设代码为F的[[Code]]内部属性的值。
- 使用10.5中描述的函数代码和argumentList执行声明绑定实例化。
换句话说:要么指定它,要么自动设置为全局对象。 它永远不会从它的父范围inheritance这个绑定,所以将父范围的thisBindiong赋给它的子节点的唯一方法是
- 将其保存在父范围的局部variables中,如var
self = this
- 注入电话/申请就像你在你的问题给你的代码。