【问题标题】:Can someone explain this function in JavaScript [duplicate]有人可以用 JavaScript 解释这个函数吗?
【发布时间】:2015-06-08 15:13:14
【问题描述】:

我正在通过在线 TUT 学习 javaScript 中的 callapply。此函数允许传递更多参数,而不是固定数量。

var calculate = function(){
        var fn = Array.prototype.pop.apply(arguments);
        return fn.apply(null, arguments);
    };

这句话让我难以理解。

var fn = Array.prototype.pop.apply(arguments);

TUT的演示者,解释如下:

我们将apply 方法绑定到arguments 对象上。这将为我们提供Function Object 并将其分配给 fn 变量。它还将从argumentsObject 中删除Function Object。因为数组的pop method 获取数组中的最后一个元素,所以它将它从数组中删除,然后分配给曾经调用过的方法。在这种情况下,fn 变量。

让我感到困惑的是:

我们将apply 方法绑定到arguments 对象上。这是 会给我们Function Object

它还会从arguments 中删除Function Object 对象。

而当我们在return语句中写:

 return fn.apply(null, arguments);

我们为什么要包含null

【问题讨论】:

  • 这段代码不验证我称之为的任何方式
  • apply 中,第一个参数是上下文(this)。在Array.prototype.pop.apply(arguments) 中,您使用arguments 作为上下文,它是一个类似数组的对象(不是实际的Array 对象)。那是因为你不能做arguments.pop(),因为arguments 不共享Array.prototype...它实际上不是Array 对象。
  • 所以在第一个apply 中,你不需要第二个参数。但是,在fn.apply(null, arguments) 中,您将null 作为第一个参数传入,因为不需要上下文。但是,您将 arguments 作为第二个参数传入,因为它可以被函数使用。
  • 我不知道为什么人们一直关闭这个问题......
  • arguments 是伪数组,在其上调用 pop(获取最后一个元素 = 函数),然后在其余参数上运行它。计算(1,2,3,4,5,function() { console.log(arguments); });

标签: javascript arrays


【解决方案1】:

Array.prototype.pop.apply(arguments);

当你有一个函数时,会自动生成一个arguments 对象,它是一个类似数组的参数对象。如果你调用这个假函数:

someFunction('hello', 'world');

someFunction 看起来像这样:

function someFunction() {
    console.log(arguments);
}

console.log 将输出['hello', 'world']。但是,不要混淆......这不是Array 对象!它是一个“类似数组”的对象。因此,你不能说arguments.pop()... 因为arguments 没有那个方法(它属于Array.prototype)。但是,普通的Array 对象确实可以访问Array.prototype(例如[1,2,3].pop() // => [1,2])。

当您说.apply() 时,第一个参数是上下文...它设置this。所以说真的,Array.prototype.pop.apply(arguments) 是模仿arguments.pop() 的聪明方法。但是你不能做arguments.pop(),因为它没有pop 方法。

return fn.apply(null, arguments); 中,null 是第一个参数,因为我们不需要为此示例设置新的上下文。 arguments 是第二个参数,因为它被传入以与 fn 一起使用。

.apply() 返回一个函数对象,所以它返回如下内容:

function() { ... }

然后我们可以稍后调用该函数。

顺便说一句,.pop() 改变了原始对象(在这种情况下,类似数组的对象arguments)。所以你将arguments 传递给fn,但它缺少之前的最后一项。

【讨论】:

    【解决方案2】:

    根据MDN

    语法

    fun.apply(thisArg, [argsArray])

    参数

    这个参数: 这为有趣的呼吁提供了价值。注意,这可能不是方法看到的实际值:如果方法是非严格模式代码中的函数,null 和 undefined 将被替换为全局对象,原始值将被替换为盒装。

    参数数组: 一个类似数组的对象,指定应该调用 fun 的参数,如果不应该向函数提供参数,则为 null 或 undefined。从 ECMAScript 5 开始,这些参数可以是通用的类数组对象而不是数组。请参阅下面的浏览器兼容性信息。

    【讨论】:

      【解决方案3】:

      传递给calculate 的最后一个参数被假定为一个函数。它从arguments 列表中弹出。 (使用apply 因为arguments 不是真正的数组。)

      这个弹出函数 (fn) 与 arguments 列表的其余部分一起调用。 (所有其他参数都传递给calculate)。 arguments 列表不再包含 fn,因为 pop() 修改了原始对象。

      使用

      NULL 是因为在没有 this 值的情况下调用了 fn。 (见MDN


      如果你打电话给calculate,比如

      calculate(2, 3, function(a, b){ return a + b });
      

      它将返回 5。

      【讨论】:

        猜你喜欢
        • 2011-01-16
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-19
        • 1970-01-01
        相关资源
        最近更新 更多