fn.apply with first param null或undefined

nav*_*een 3 javascript

我很困惑fn.apply.例如,

考虑一下这个片段

Array.min = function(){
    return Math.min.apply( Math, arr );
}
Run Code Online (Sandbox Code Playgroud)

我能理解这一点.我理解fn.apply为,

调用具有给定值的函数和作为数组提供的参数

但下面的片段也有效

Array.min = function(){
    return Math.min.apply( null, arr );
}

Array.min = function(){
    return Math.min.apply( undefined, arr );
}
Run Code Online (Sandbox Code Playgroud)

MDN将此解释为,

如果该方法是非严格模式代码中的函数,则null和undefined 将替换为全局对象,并且原始值将被加框

我真的不明白我大胆的部分.那句话是什么意思?任何人都可以详细说明一下吗?

Ble*_*der 9

"全局对象"是全局对象.只需阅读规范:

在控制进入任何执行上下文之前创建唯一的全局对象.

除了本规范中定义的属性外,全局对象还可能具有其他主机定义的属性.这可能包括一个属性,其值是全局对象本身; 例如,在HTML文档对象模型window中,全局对象的属性是全局对象本身.

在浏览器中,您实际上是在调用Math.min.apply(window, arr),您可以验证:

(function() {
    console.log(this);  // Logs `Window {...}`
}).apply(undefined);
Run Code Online (Sandbox Code Playgroud)

这是非严格模式的许多问题之一.this有时变得window,你默默地最终创建全局属性.在严格模式下,this将真正undefined:

(function() {
    'use strict';

    (function() {
        console.log(this);  // Logs `undefined`
    }).apply(undefined);
})();
Run Code Online (Sandbox Code Playgroud)

"原始值将被加框"只是说数字和字符串等基元将被"装箱"到容器对象中,因为基元本身不是对象.同样,您可以验证这一点:

(function() {
    console.log(this);  // Logs `Number {}`, not `2`
}).apply(2);
Run Code Online (Sandbox Code Playgroud)

这里有一些关于基元的更多信息:为什么JavaScript原语不是对象的实例?