JavaScript `arguments` 是否包含 `this`?

Does JavaScript `arguments` contain `this`?

我正在尝试理解 JavaScript 的 arguments 函数中的隐式变量。有些教程删除了它的第 0 个元素,并说它包含 this 但其他一些教程没有删除第 0 个元素。我很困惑。

我写了这个代码示例,它显示 arguments 不包含 this:

function aaa () {
    console.log(arguments[0])
}

aaa(1,2,3);

有没有可能有时 arguments 包含 this?我想知道为什么有些教程在使用 arguments.

之前切掉第 0 个元素

很可能你有一个像 blah(x) 这样的函数,在这种情况下,你去掉第一个参数,因为它已经被捕获为变量 x,你想要其余的参数已通过。

第一个参数不是 this

Arguments 是传递给函数的原始参数的数组*,与 "this" 变量没有直接关系。

也就是说,不同的教程可能会尝试使用函数的作用域(作用域 => "this" 变量)来解释函数引用的工作原理等。这很容易涉及传递一个数组并关闭第一个参数。

考虑这个简单的片段:

var sample = function(a,b,c){ 
    console.log(arguments, this); 
}; 
sample(1,2,3);

输出:

[1, 2, 3], window

我们现在知道,"this"是一个与函数作用域有关的特殊变量。 plenty of articles 描述了它 does/how 它的工作原理,但在这种情况下,您可能已经看到以 .call 或 .apply 的方式使用的东西:

sample.call(sample, 1, 2, 3)

sample.apply(sample, [1,2,3])

这些片段都做同样的事情 - 它们将函数的 "this" 作用域从 window 对象(因为 "sample" 被声明为全局函数)转换为 "sample"函数本身,并传递参数1、2和3。他们输出:

[1, 2, 3], [sample function]

有些教程会在这种情况下移开第一个参数的原因是,通常有 "helper" 函数可以在更改范围时使其更加明显,而且很多时候这些辅助函数将其作为第一个参数参数,新函数执行的范围。因此,他们关闭第一个参数,并在(本质上)调用应用程序时使用它。一个常见的例子是 bind(),像这样:

Function.prototype.bind = function(scope){
    var me = this,
        args = Array.prototype.slice.apply(arguments, [1]);

        return function () {
            var handlerArgs = []; 
            for (i = 0; i < args.length; i++) {
                handlerArgs.push(args[i]);
            }
            for (var i = 0; i < arguments.length; i++) {
                handlerArgs.push(arguments[i]);
            }
            me.apply(scope, handlerArgs);
        };
};

现在,您可以拨打:

var bound = sample.bind(sample, 1);
bound(2,3);

...并得到输出:

[1, 2, 3] [sample function]

你可以看到我们在最初绑定函数时传递了一些参数(范围和第一个参数),此时我们切掉了第一个参数("sample",因为那是 "scope" 并且必须以不同于任何其他参数的方式处理),然后在调用 bound() 时,将 1 以及 2 和 3 推入最终参数列表。

起初有点困惑,但希望能有所帮助。

*技术上 array-like.