0

the problem is that when i use test.call(), it calls into my call implementation of the prototype but when i use test(), it doesnt call call(). i want to be able to use test to trigger prototype.call(). code below:

            Function.prototype.call = function () {
            //do something...
            return this(); // call original method
        }

        function test() {
            alert("test");
        }

 test.call(); //calls prototype.call()
    test(); //doesnt call prototype.call()

2 Answers 2

2

Why would you expect test() to invoke Function.prototype.call? They're different functions.

The native .call() method that you're overwriting is not invoked every time a function is invoked. It's only invoked when you invoke it.

Invoking .call() does invoke test() because that's what it's designed to do. It expects a function as its context (this value), and invokes that function. But that doesn't mean .call() has anything to do with any other function invocation.

Sign up to request clarification or add additional context in comments.

12 Comments

thanks for the clarification. So how is it possible to do it. I need to call a function whenever any other function is invoked.
It is simply not possible. Why do you think you need this?
@AliTarhini: Not automatically. You could manually decorate the functions, but you'd need foreknowledge of those functions.
I need to create a log of all functions being executed
Sounds like a job for a debugger.
|
1

Here's a solution that I just whipped up (credit goes to cliffsofinsanity for pointing out a crucial error with the code and correcting it). It logs all non-standard functions called after a certain point, in the order that they were called.

// array of all called functions
var calledFunctions = [];

// custom func object that has name of function and 
// and the actual function on it.

function func(_func, name) {
    return function() {
        calledFunctions.push(name)
        return _func.apply(this, arguments);
    };
}

test = function() {
    alert("hi");
}

otherTest = function() {
    alert("hello");
}

// put this bit somewhere after you've defined all your functions
// but *before* you've called any of them as all functions called
// after this point are logged. It logs all non-standard functions
// in the order that they are called.
for (prop in window) {
    if (window.hasOwnProperty(prop) && typeof window[prop] === 'function' && window[prop].toString().indexOf('[native code]') < 0) {
        window[prop] = func(window[prop], prop);
    }
}

otherTest();
test();
otherTest();

console.log(calledFunctions);​

Working demo can be found here.

6 Comments

Keep in mind that any arguments passed to the functions are lost, as well as the return value, and the context of the function may be altered. You should do return that._func.apply(this, arguments);. Also, you could really do this without a constructor. You're having to close over that to reference _func and name as properties, so instead you could skip the that object, and just close over the parameters. jsfiddle.net/TkZ6d/10
Very interesting, thanks for pointing that out! I've edited my answer and given you credit.
just wondering what that means: window[prop].toString().indexOf('[native code]') < 0
@AliTarhini: It converts a property of the window to a string representation then checks to see if the string "[native code]" is found. If it is, then the property is something's "native" or standard to Javascript.
thanks. The above code work perfectly. Is it possible to get script that is not embedded inside a function such as inline scripts that are writen directly inside script tags?
|

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.