值null是表示null或“空”的JavaScript文字 值,即不存在对象值。它是JavaScript之一 原始价值观。
function getMax(arr){
return Math.max.apply(null, arr);
}
不会明确地传递关键字this
更清晰,或者至少更具可读性?然后,在这一点上,我可能不明白你为什么要使用null
。
答案 0 :(得分:11)
使用null作为第一个参数调用apply
就像调用函数而不为this
提供任何对象。
apply
方法有什么作用?
apply()
方法调用具有给定this
值的函数arguments
作为数组(或类数组对象)提供。
fun.apply(thisArg, [argsArray])
thisArg
为乐趣召唤提供的价值。请注意,这可能不是 是方法看到的实际值:如果方法是函数 非严格模式代码,null和undefined将替换为 全局对象和原始值将被装箱。
可以找到进一步的文档here。
答案 1 :(得分:10)
为什么你会通过' null'要适用'或者打电话'?
如果没有值,您希望为函数内的this
指针指定值,并且您调用的函数不会期望特定的this
值以便正常运行。< / p>
不会明确地传递关键字这个更清楚吗?或至少 更具人性化。然后在这一点上我可能不明白为什么 你会使用null。
在您的具体情况下,最好的方法是Math
对象:
function getMax(arr){
return Math.max.apply(Math, arr);
}
虽然事实证明,作为Math.max.apply(...)
的第一个参数传递的内容并不重要(仅因为Math.max()
的实现细节),但传递Math
集this
指向与Math.max(1,2,3)
正常调用时设置的完全相同的指针,因此这是最安全的选项,因为您最好模拟对Math.max()
的正常调用。< / p>
为什么你会通过&#39; null&#39;要适用&#39;或者打电话&#39;?
以下是一些更多详细信息...使用.call()
或.apply()
时,如果您没有要设置null
的特定值,则可以传递this
指向并且您知道您正在调用的函数不期望this
具有任何特定值(例如,它在其实现中不使用this
)。
注意:将null
与.apply()
或.call()
一起使用通常仅使用仅出于命名空间原因的方法的函数,而不是出于面向对象的原因。换句话说,函数max()
是Math
对象上的一个方法,只是因为命名空间的原因,而不是因为Math
对象具有方法.max()
需要的实例数据访问。
如果你这样做:
function foo() {
this.multiplier = 1;
}
foo.prototype.setMultiplier = function(val) {
this.multiplier = val;
}
foo.prototype.weightNumbers = function() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += (arguments[i] * this.multiplier);
}
return sum / arguments.length;
}
var x = new foo();
x.setMultiplier(3);
var numbers = [1, 2, 3]
console.log(x.weightNumbers.apply(x, numbers));
当您调用.apply()
的方法需要访问实例数据时,您必须将相应的对象作为第一个参数传递,以便该方法具有正确的this
指针来完成其工作预期
答案 2 :(得分:1)
我回答这个问题有点迟了。我会尝试在这里给出一个很长的描述性解释。
JavaScript中的null是什么?
值null是一个文字(不是像undefined那样的全局对象的属性)。它是JavaScript的原始值之一。
在API中,通常会在可以预期对象但没有对象相关的位置检索null。
fun.apply(thisArg,[argsArray])
thisArg :为乐趣调用提供的值。请注意,这可能不是方法看到的实际值:如果方法是非严格模式代码中的函数,则null和undefined将替换为全局对象,并且原始值将被装箱。
argsArray :一个类似数组的对象,指定应该调用fun的参数,如果不应该为函数提供参数,则为null或undefined。从ECMAScript 5开始,这些参数可以是类似通用数组的对象而不是数组。请参阅下面的浏览器兼容性信息
如果您使用&#39;严格模式&#39;,则建议通过此或 数学作为参数。
答案 3 :(得分:1)
我发现这很有用的一种情况是,我正在调用的功能已经绑定到特定的上下文。
因为绑定函数无法反弹,并且始终使用传递给thisArg
的{{1}}来调用它们,所以将bind
传递给{{1}毫无用处}或thisArg
。来自source:
call
函数将创建一个新的绑定函数(BF)。...调用绑定函数时,它将在apply
上调用内部方法bind()
,并带有以下参数{{1 }}。
这是一个例子:
[[Call]]
答案 4 :(得分:1)
当您希望将对某项操作的责任传递给在运行时确定的函数,并将可变数量的参数传递给该函数时,应用很有用。在执行此操作时,您可能有也可能没有任何适当的“此”上下文。
例如,我使用编写的库来方便侦听和引发使用apply的应用程序事件。
我希望能够引发这样的事件:
EventManager.raise('some:event-name', arg1, arg2, arg3, ..);
..,并使用该参数列表(arg1,arg2等)调用该事件的所有已注册处理程序。因此,在raise函数中,它将遍历为该事件名称注册的处理程序并调用它们,并传递除事件名称之外的所有传入参数,例如:
var args = [];
Array.prototype.push.apply(args, arguments);
args.shift();
for (var l in listeners) {
var listener = listeners[l];
listener.callback.apply(listener.context, args);
}
调用注册的处理程序(listener.callback)时,apply用于传递可变数量的参数。在这里,我已允许侦听器在定义侦听器时为其事件处理程序提供此上下文,但是该上下文可能未定义,或者可能为null,这很好。
很长一段时间内,raise函数甚至都没有促进使用任何回调上下文。最终我遇到了对它的需求,因此我对它提供了支持,但是大多数时候我并不是真的需要或使用它。