3

Hello I was reading "JavaScript: the definitive guide" 6th edition and tried one of the examples at 9.1 Classes and Prototypes.

function range (from, to) {
    var r = Object.create(range.methods);

    r.from = from;
    r.to = to;
    return r;
}

range.methods = {
    includes: function(x) { 
        return this.from <= x && x <= this.to; 
    },
    foreach: function(f) {
        for(var x = Math.ceil(this.from); x <= this.to; x++) 
            f(x);
    },
    toString: function() { 
        return "(" + this.from + "..." + this.to + ")"; 
    }
};

Loading this into console throws an error

Uncaught TypeError: Illegal invocation class.js:31. range.methods.foreach class.js:31 (anonymous function)

I guess intention of foreach method is to pass a function name as an argument

var r = range(1, 3);
r.foreach(console.log);

Any ideas how to fix this error?

2

2 Answers 2

9

It happens because you detached log method from console object, while console.log expects context (this) to be console, not Window as it becomes when you lose context. If you want to use console.log as a function you should explicitly tell it what context to use.

r.foreach(console.log.bind(console));

Function.prototype.bind is your friend in this case.

For future readers: ES6 style would also allow you to use arrow functions for this which would be even more concise:

r.foreach(x => console.log(x))
Sign up to request clarification or add additional context in comments.

2 Comments

@techfoobar Soon there will be another classical way to do it r.foreach(x => console.log(x)) :)
Hmm.. I need to stay upto date on the specs. Thanks. :)
4

Log cannot be called outside of the console object, you're passing in the function, but not the context.

r.foreach(function(a){
    console.log(a);
});

This works without any issues.

2 Comments

Nice, it works, but why ? In fact it was called with the object console, right ?
@DontVoteMeDown When you pass a function you pass the function, but not the parent information, calling the function inside your loop then runs into an issue of the this object being the window instead of the console, and the function generates an error.

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.