I’m trying to invoke addEventListener() using apply() method. The code is like:
function rewrite(old){
return function(){
console.log( 'add something to ' + old.name );
old.apply(this, arguments);
}
}
addEventListener=rewrite(addEventListener);
It doesn’t work. The code works for normal JavaScript method, for example,
function hello_1(){
console.log("hello world 1!");
}
hello_1=rewrite(hello_1);
Need help!
Thanks!
You can’t count on
addEventListenerbeing a real Javascript function, unfortunately. (This is true of several other host-provided functions, likewindow.alert). Many browsers do the Right Thing(tm) and make them true Javascript functions, but some browsers don’t (I’m looking at you, Microsoft). And if it’s not a real Javascript function, it won’t have theapplyandcallfunctions on it as properties.Consequently, you can’t really do this generically with host-provided functions, because you need the
applyfeature if you want to pass an arbitrary number of arguments from your proxy to your target. Instead, you have to use specific functions for creating the wrappers that know the signature of the host function involved, like this:When you call that, passing in an element, it returns a function that will hook up event handlers to that element via
addEventListener. (Note that IE prior to IE8 doesn’t haveaddEventListener, though; it usesattachEventinstead.)Don’t know if that suits your use case or not (if not, more detail on the use case would be handy).
You’d use the above like this:
Note that we didn’t pass the element reference into
proxywhen we called it; it’s already built into the function, because the function is a closure. If you’re not familiar with them, my blog post Closures are not complicated may be useful.Here’s a complete example:
Regarding your question below about
func.apply()vs.func(), I think you probably already understand it, it’s just that my original wrong answer confused matters. But just in case:applycalls function, doing two special things:thiswill be within the function call.As you probably know,
thisin Javascript is quite different fromthisin some other languages like C++, Java, or C#.thisin Javascript has nothing to do with where a function is defined, it’s set entirely by how the function is called. You have to setthisto the correct value each and every time you call a function. (More aboutthisin Javascript here.) There are two ways to do that:thisto the object within the call. e.g.,foo.bar()setsthistofooand callsbar.applyorcallproperties; those setthisto their first argument. E.g.,bar.apply(foo)orbar.call(foo)will setthistofooand callbar.The only difference between
applyandcallis how they accept the arguments to pass to the target function:applyaccepts them as an array (or an array-like thing):whereas
callaccepts them as individual arguments:Those both call
bar, setingthistofoo, and passing in the arguments 1, 2, and 3.