在Javascript中是否有相当于.apply的东西,不会改变this的值?

发布于 2024-10-21 04:43:53 字数 170 浏览 9 评论 0原文

看起来很简单,我想调用一个带有参数数组的函数。当然,我可以说 func.apply(this, ['some', 'arguments']); 但这会改变 func< 内 this 的值/代码>。知道如何在不改变它的情况下做到这一点吗?

Seems easy enough, i want to call a function with array of arguments. Sure, i can say func.apply(this, ['some', 'arguments']); but that will change the value of this inside func. Any idea how to do this without changing it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

安静被遗忘 2024-10-28 04:43:53

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

查看“输入执行上下文” 部分ECMAScript 规范:当您调用函数时,this 的值由其左侧的内容(称为激活对象)决定。让我们创建一个名为 steve 的函数,并将他放入一个对象中:

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

...当我们将 steve 称为 obj.method() 时,他的 thisobj,因为 obj 是激活对象。

棘手的情况是当函数调用的左侧没有任何内容时:

steve(); // Who am I ?!

函数调用的左侧没有任何内容 — 实际上,它是 null - 因此 this 的值被设置为全局对象的默认值(Web 浏览器中的 window,Node.js 中的 global , ETC。)。

因此,事实上,您每次调用函数时都会设置该函数的 this

PS 调用 steve.apply(null, []) 相当于调用 steve()

You cannot, because of the way this works in JavaScript. Read on:

Going by the "Entering An Execution Context" section of the ECMAScript spec: when you call a function, the value of this is determined by what's to it's left (called the activation object) . Let's create a function called steve, and put him in an object:

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

…when we call steve as obj.method(), his this is obj, because obj was the activation object.

The tricky case is when nothing is to the left of a function call:

steve(); // Who am I ?!

There's nothing to the left of the function call — effectively, it's null — so the value of this is set to a default value of the global object (window in web browsers, global in Node.js, etc.).

So you are, in fact, setting a function's this every time you call it.

P.S. calling steve.apply(null, []) is equivalent to calling steve().

残龙傲雪 2024-10-28 04:43:53

注意,在 ES6 中你还可以这样写:

func(...someArray)

这里 this 变成 func 内的 Window,这是没有用的。但是如果你

obj.func(...someArray)

func里面写:this将会是obj

这可能是我 5 年前一直在寻找的功能,但那是 5 年前的事了,所以谁还记得:)

Note that in ES6 you can also write:

func(...someArray)

Here this becomes Window inside func, which is of no use. But if you write:

obj.func(...someArray)

this in inside func will be obj.

This may be the feature i was looking for 5 years ago, but that was 5 years ago, so who remembers :)

寻找我们的幸福 2024-10-28 04:43:53

调用函数时,this 的值并不神秘,具体取决于它如何“正常”调用(没有 callapply):

func(); // `this` is the global object, or undefined in ES5 strict mode
obj.func(); // `this` is `obj`

所以为了避免“更改”this 的值,只需将正确的值传递给 apply,具体取决于您如何“正常”调用它:

func.apply(undefined, []); // global object, or undefined in ES5 strict mode
obj.func.apply(obj, []);

The value of this is no mystery when calling a function, depending on how it is called "normally" (without call or apply):

func(); // `this` is the global object, or undefined in ES5 strict mode
obj.func(); // `this` is `obj`

So to avoid "changing" the value of this, just pass in the correct value to apply, depending on how you would call it "normally":

func.apply(undefined, []); // global object, or undefined in ES5 strict mode
obj.func.apply(obj, []);
慕烟庭风 2024-10-28 04:43:53

如果您单独调用函数,请传递null

func.apply(null, ['some', 'arguments']);

如果您调用的函数是对象的方法,请传递该对象。

var arr = [];
arr.push.apply(arr, ['some', 'arguments']);

为了匹配 this 的工作方式。

If you are calling a function alone, pass null.

func.apply(null, ['some', 'arguments']);

If you are calling a function that is a method of an object, pass that object.

var arr = [];
arr.push.apply(arr, ['some', 'arguments']);

In order to match a how this works.

鸠书 2024-10-28 04:43:53

你想要的没有多大意义。

在 ecmascript 标准中 this 是这样定义的:

11.1.1 this 关键字 this 关键字的计算结果为
当前执行的ThisBinding
上下文。

函数执行上下文的 thisBinding 解析是这样指定的:

10.4.3 输入功能代码 当以下步骤执行时
控制进入执行上下文
对于包含在
函数对象F,调用者提供
thisArg,以及调用者提供的
参数列表:

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

换句话说:要么您指定它,要么它自动设置为全局对象。它永远不会从其父作用域继承 this 绑定,因此将父作用域的 thisBindiong 赋予其子作用域的唯一方法是将

  1. 其保存在父作用域中的局部变量中,例如 var self = this
  2. 使用 call/apply 注入它,就像您在问题中给出的代码一样。

What you want doesn't make much sense.

In the ecmascript standard this is defined this way:

11.1.1 The this Keyword The this keyword evaluates to the value of the
ThisBinding of the current execution
context.

The thisBinding resolution for a functions execution context is specified this way:

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.

In other words: either you specify it or it is automatically set to the global object. It will never inherit the this binding from it's parent scope, so the only way to give the thisBindiong of the parent scope to it's children is either by

  1. save it in a local variable in the parent scope like var self = this
  2. inject it with call/apply like the code you gave in your question.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文