Maintaining a unique array of functions
I assumed that functions could passed around like normal values in Javascript. I thought that they evaluated to some address. From the output of the following example, I seem to be right.
var f = function() { console.info('f'); };
var v = function() { console.info('v'); };
var arr = [];
arr.push(f);
arr.push(f);
arr; // [function(), function()]
arr.uniq(); // [function()]
arr.push(开发者_Go百科f);
arr.push(f);
arr.push(v);
arr; // [function(), function(), function()]
arr.without(f); // [function()]
arr.first()(); // v
However, once I applied this observation to "object oriented" code, uniq
and without
stopped working.
A = Class.create({
initialize: function() {
},
callback: function() {
},
add: function() {
b.add(this.callback.bind(this));
}
remove: function() {
b.remove(this.callback.bind(this));
}
});
a = new A();
B = Class.create({
initialize: function() {
this.funcs = [];
},
add: function(func) {
this.funcs.push(func);
this.funcs = this.funcs.uniq();
},
remove: function(func) {
this.funcs = this.funcs.without(func);
}
});
b = new B();
a.add(); // b.funcs = [function()]
a.add(); // b.funcs = [function(), function()]
a.remove; // b.funcs = [function(), function()]
Every time you call b.add
, a.funcs
grows larger; uniq
does not strip the duplicates. And every time you call b.remove
, a.funcs
does not shrink; without
has failed to find the function.
It appears to me that I'm appending functions that resolve to different address every time. Does bind
give a new address each time? How do I fix this? I want to ensure that there's never two of the same function in a
's this.funcs
; It's okay if two functions defined in two different places do the same thing, but not okay if the same function handle were in the array twice.
You've got the right idea - that JS functions are first-class citizens, and that bind
returns a new function each time it's called. However, what you want to do is impossible. It is computationally impossible to determine if two different functions do the same thing for all inputs.
There's a similar question I saw a little while ago, let me see if I can dig it up. here it is.
精彩评论