在Javascript中是否有相当于.apply不改变这个值?

看起来很简单,我想用参数数组来调用一个函数。 当然,我可以说func.apply(this, ['some', 'arguments']); 但是这会改变this func的价值。 任何想法如何做到这一点而不改变它?

你不能, 因为this在JavaScript中的工作方式 。 阅读:

通过ECMAScript规范的“input执行上下文”部分:当您调用一个函数时,其值由左边的内容决定(称为激活对象 )。 我们来创build一个叫做史蒂夫的函数,并把它放在一个对象中:

 function steve(){} var obj = { method: steve }; 

…当我们把obj.method()称为steve时,他的thisobj ,因为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值并不神秘,这取决于它是如何被调用的“正常”(没有callapply ):

 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:

  1. 如果函数代码是严格代码,则将ThisBinding设置为thisArg。
  2. 否则,如果thisArg为null或未定义,请将ThisBinding设置为全局对象。
  3. 否则,如果Type(thisArg)不是Object,则将ThisBinding设置为ToObject(thisArg)。
  4. 否则将ThisBinding设置为thisArg。
  5. 让localEnv是调用NewDeclarativeEnvironment传递F的[[Scope]]内部属性的值作为参数的结果。
  6. 将LexicalEnvironment设置为localEnv。
  7. 将VariableEnvironment设置为localEnv。
  8. 设代码为F的[[Code]]内部属性的值。
  9. 使用10.5中描述的函数代码和argumentList执行声明绑定实例化。

换句话说:要么指定它,要么自动设置为全局对象。 它永远不会从它的父范围inheritance这个绑定,所以将父范围的thisBindiong赋给它的子节点的唯一方法是

  1. 将其保存在父范围的局部variables中,如var self = this
  2. 注入电话/申请就像你在你的问题给你的代码。