0

I've heard that it's possible to do something like this

this[func].apply(this, Array.prototype.slice.call(arguments, 1));

But to have access to the arguments object I need to be inside that function.

So, if I am, for example, running a code in the function function1, is there a way to get the arguments of a different function function2?

The whole problem is that I want to add events to any given element. But this element might already have another event attached to it. so, if I have, for example, an 'onclick' event attached to an element, I would do the following:

var event = 'onclick';
if(typeof currentElement[event] === 'function'){
    cf = currentElement[event];
    f = function(){
        cf();
        func();
    }
}else f = func;

currentElement[event] = f;

Now both functions, the new function and the previous function, are being called. The problem is that the arguments being passed to the previous function were lost with this method.

Does anyone know if it is possible to not lose the arguments when we call a function dynamically like in my example?

OBS: jQuery is not an option :/

2
  • Please just use addEventListener or attachEvent; so much easier. Commented Oct 24, 2013 at 4:55
  • For this specific case, you know what arguments both functions receive - they're the same arguments and can't change. It's the event object in all browsers except IE where it's undefined. Commented Oct 24, 2013 at 5:07

3 Answers 3

2

Sounds like using addEventListener would work better for you. It lets you attach multiple listeners (functions) to a single element:

elem.addEventListener("click", function() {
  console.log("click listener 1");
});

elem.addEventListener("click", function() {
  console.log("click listener 2");
});

Note, according to MDN, addEventListener is supported in IE >= 9.

If you did want to continue down your current path, you could do:

f = function(){
    cf.apply(this, arguments);
    func.apply(this, arguments);
}
Sign up to request clarification or add additional context in comments.

Comments

1

For you specific case, it's not necessary to figure out what arguments are passed to the function since you know what it is - the event object in all browsers except (older) IE where its nothing (undefined).

So the code can simply be:

var event = 'onclick';
if(typeof currentElement[event] === 'function'){
    cf = currentElement[event];
    f = function(e){
        cf(e);
        func(e);
    }
} else f = func;
currentElement[event] = f;

If possible use addEventListner and attachEvent as fallback to play nicely with other scripts that may run on your page.


Additional discussion:

In general, it is never necessary to figure out what has been passed to the callback function because that doesn't even make sense. The programmer cannot determine what to pass to the callback, it's the event emitter that determines what gets passed. In this case its the event object but it's a general rule.

Say for example we have an API that queries our database and returns some data:

function my_api (query) {}; // returns an object where a callback may
                            // be attached to the oncomplete property

The API documentation mentions:

my_api() returns an API object.

API object - has one property - oncomplete where a callback may be attached to handle data returned from the api call. The callback will be called with one argument - the returned data or no argument (undefined) if an error occured.

OK. So we use it like this:

var db = my_api('get something');
db.oncomplete = function (data) {alert(data)};

Now, if we want to wrap that oncomplete event in another event handler, we don't need to know what data it accepts since it's the API object that determines what to pass to the function, not the function! So we simply:

var tmp = db.oncomplete;
db.oncomplete = function (x) {
    new_callback(x);
    tmp(x);
}

We get the x argument not from querying the previous callback but from the documentation.

Comments

0
somefunction.arguments //Use the arguments property to get arguments of another function

2 Comments

caller is deprecated and should be avoided. The second half of go-oleg's answer is a better approach
@MattGreer I didn't know that. I can't imagine why they would do such a thing. Well, that was an example, anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.