1

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.

4
  • Any particular reason you're not just using bind()? Is this an exercise? Commented Jan 18, 2015 at 11:28
  • Yes it's just an exercise. Because that's the most fun part about programming, you can do whatever you want ;) Commented Jan 18, 2015 at 11:30
  • Interesting, my guess is that for some reason in node console relies on bind to work. When I renamed your prototype method to myBind it works perfectly. Commented Jan 18, 2015 at 11:37
  • For improvement: you can use argumentsArray = Array.prototype.slice.call(arguments,1), thus eliminating a for lus. Commented Jan 18, 2015 at 11:57

1 Answer 1

1

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)));
    };
};
Sign up to request clarification or add additional context in comments.

4 Comments

thanks! But why does my implementation still doesn't output any value? I still get nothing when I run it via node. Running this on browser seems to work correctly.
@I_Debug_Everything because you are not applying arguments of called function
@I_Debug_Everything return self.apply(obj,argumentsArray); must be return self.apply(obj, argumentsArray.concat([].slice(arguments))). See my realization also
@I_Debug_Everything node will use your bind method for console.log

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.