我有以下代码
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);
最佳答案
这里发生的是,每次触发click
事件时,都会再次实例化匿名处理程序,因此Stuff
函数也会被实例化。
不,这不是您的第二个代码块中发生的事情。每次触发click
时,都会将相同的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/