I_Debug_Everything
I_Debug_Everything

Reputation: 3816

Trying to simulate function.bind() on node.js

I'm using node v0.10.28

I've been trying to simulate the function bind() method as a prototype of a function and I've come across a strange issue.

Function.prototype.bind = function() {
    var obj = arguments[0],
        argumentsArray = [],
        self = this;

    // since arguments is an object and we can't call .splice() on it
    for(var i in arguments) {
        argumentsArray.push(arguments[i]);
    }

    argumentsArray.splice(0,1);

    // The following throws error when running via node, works fine on browser
    //console.log(argumentsArray); 

    return function() {
        return self.apply(obj,argumentsArray);
    }
};


function sum(y,z) {
    return this.x + y + z; 
}

var obj = { x : 8},
    f, value;

f = sum.bind(obj,1,2);

value = f();

console.log(value);

Please refer this fiddle, when I run in via node ( node demo.js ) it has some strange behavior. See the commented console.log(argumentsArray) in the fiddle, un-comment that, save it in a file and run via node will give you the following error:

TypeError: Object #<Object> has no method 'log'

Also the final console.log(value) prints nothing on the console when running it via node. The same seems to work perfectly on the browser.

Is there something I'm missing, or node doesn't allows console.log() inside of a prototype function definition or anything else?

Thanks for the help in advance.

Upvotes: 1

Views: 697

Answers (1)

alexpods
alexpods

Reputation: 48525

It because console module binds all its methods to itself (see source here). This is for you can do things like:

var log = console.log;

log('something');

console module will be initialize at the first usage. So on line

// The following throws error when running via node, works fine on browser
console.log(argumentsArray); 

node will try to initialize console module and then call log method. In process of module initialization it'll try to bind log method to itself here and as result - will call your method bind again. console module will be considered as initialized, and node will try to call its log method. But actually console is not initialized at that time. So error will be thrown.

PS:

Much simpler realization of what you are trying to do:

Function.prototype.bind = function(context) {
    var args = [].slice.call(arguments, 1);
    var self = this;

    return function() {
         return self.apply(context, args.concat([].slice.call(arguments)));
    };
};

Upvotes: 1

Related Questions