这在Chrome控制台中似乎是矛盾的:
> var forEach = Array.prototype.forEach.call;
> forEach
function call() { [native code] }
> Object.getPrototypeOf(forEach);
function () {}
> forEach([1,2,3], function(a) { console.log(a); });
Uncaught TypeError: forEach is not a function
我在JS内部函数中猜测function.call的处理方式与普通函数不完全相同吗?
答案 0 :(得分:3)
如果您想forEach(array, fn)
var forEach = Function.call.bind(Array.prototype.forEach);
现在您可以像以前一样使用它:
forEach([1,2,3], function(a) { console.log(a); });
您正在做的是将this
绑定到Array.prototype.forEach
。这只是写Array.prototype.forEach.call
的简写。
如果你想象出调用“调用”函数的方式会更容易,所以想象调用函数会这样做(实际上不是这样):
return this(arg1, arg2, etc);
现在假设bind
返回调用函数,绑定为this
到Array.prototype.forEach.call
:
return Array.prototype.forEach.call(arg1, arg2, etc);
你当然可以自己做同样的事情:
var forEach = function(array, fn) {
return Array.prototype.forEach.call(array, fn);
}
虽然我不确定哪一个会更好,但性能明智。
答案 1 :(得分:2)
在JavaScript中,函数是一等公民,就像字符串和整数一样。当您执行Array.prototype.forEach.call
时,您将获得.call
属性的值,prototype
链上的Function.prototype.call
属性为forEach
。因此,您的Function.prototype.call
变量设置为this
。
现在,当你调用一个函数时,该函数中forEach(...)
的值取决于它的调用方式。当您执行Function.prototype.call.call(null)
时,就像执行call
一样。 this
期望var forEach = Array.prototype.forEach;
forEach.call([1,2,3], function(a) { console.log(a); });
成为一个函数而不是函数,因此会抛出错误。
您可能需要以下内容:
var forEach = Array.prototype.forEach.bind([1,2,3]);
forEach(function(a) { console.log(a); });
或者也许:
{{1}}
答案 2 :(得分:2)
在内部依赖this
的函数必须在与其所有者"分离时才能正常工作,因为对于未绑定的函数,this
值将是由obj.func()
值引用的对象。 func()
中点的左侧。如果直接从当前范围调用函数(例如this
),则window
将指向this
。
因此,在下面的代码中,forEach
在调用window
时将Array.prototype.forEach
为var forEach = Array.prototype.forEach.call;
forEach([1, 2], function () {}); //this inside forEach is window
,而您需要call
。{/ p>
Array.prototype.forEach
要解决该问题,我们可以将 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
forEach([1, 2, 3], function (num) {
console.log(num);
});
绑定到def exact_change( target_amount, L ):
if target_amount > sum(L):
return False
elif target_amount == 0:
return True
elif target_amount < 0:
return False
elif target_amount > 0 and L==[]:
return False
elif target_amount == L:
return True
else:
loseit = exact_change(target_amount, L[1:])
useit = exact_change(target_amount, L[0])
return loseit or useit'
。
>>> exact_change( 42, [25, 1, 25, 10, 5, 1] )
True
>>> exact_change( 42, [25, 1, 25, 10, 5] )
False
>>> exact_change( 42, [23, 1, 23, 100] )
False
>>> exact_change( 42, [23, 17, 2, 100] )
True
>>> exact_change( 42, [25, 16, 2, 15] )
True # needs to be able to "skip" the 16...
>>> exact_change( 0, [4, 5, 6] )
True
>>> exact_change( -47, [4, 5, 6] )
False
>>> exact_change( 0, [] )
True
>>> exact_change( 42, [] )
False