我有以下代码
var arr = [];
$("#Target").click(function () {
function Stuff() {
console.log("Dummy");
}
var found = false;
for (var i = 0; i < arr.length; i++) {
found = found || arr[i] == Stuff;
}
if (!found)
arr.push(Stuff);
alert(arr.length);
});
每次单击按钮时,它都会增加数组的计数。但是,如果我这样修改代码
function Stuff() {
console.log("Dummy");
}
var arr = [];
$("#Target").click(function () {
var found = false;
for (var i = 0; i < arr.length; i++) {
found = found || arr[i] == Stuff;
}
if (!found)
arr.push(Stuff);
alert(arr.length);
});
它检测相等性并且数组最多包含 1 个元素。 这里发生的是每次触发
在第一个代码块中,每次触发事件时都会实例化匿名函数。在第二个代码块中,由于 click
事件时,都会再次实例化匿名处理程序,Stuff
函数也是如此。Stuff
函数是一个全局函数(读作“window
对象的属性”),所以它没有被实例化。
我的问题是,是否有一种既定的方法来测试此类函数的相等性?
PS:我知道有一个像
这样的解决方法arr[i].toString() == Stuff.toString();
但我想克制这种“巫术”
编辑
更多细节:我想创建一个函数
$.throttle = function(func, delay){
// Here I need to check whether this function was already passed,
// and if yes, I need to clear previous timeout and create new
}
也可以这样称呼
$.throttle(function () { console.log("Foo"); }, 5000);
最佳答案
What is happening here is that each time
click
event is fired anonymous handler is instantiated again, so isStuff
function.
不,这不是您的第二个代码块中发生的事情。每次 click
触发时,same Stuff
函数都会被推送到数组中;匿名函数仅由 click
处理程序运行,而不是由它实例化。 (它由连接 click
处理程序的代码实例化。)
如果你有两个对一个函数的引用,想知道它们是否引用同一个函数,你可以用===
或==
来比较它们:
var ref1 = Stuff;
var ref2 = Stuff;
console.log(ref1 === ref2); // true
console.log(ref1 === Stuff); // true
console.log(ref2 === Stuff); // true
如果您想创建一个函数的两个不同副本(如在您的第一个代码块中)并查看它们是否具有相同的代码,则没有官方方法可以做到这一点。您可以像您指出的那样比较 toString
的结果(尽管规范实际上并不要求 toString
返回代码),但是这会比较它们的代码内容(如果有效),它不会比较它们的上下文。考虑:
function foo(bar) {
return function() {
alert(bar);
};
}
var f1 = foo("one");
var f2 = foo("two");
f1(); // alerts "one"
f2(); // alerts "two"
console.log(f1.toString() === f2.toString()); // true
我们从调用 foo
得到的函数中有相同的代码,但它们不是等价的函数。据我所知,没有标准的方法来比较函数的等效性,只有同一性。
关于javascript - 两个匿名函数的相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25595173/