5

I met a weird problem when I try to understand the code in the Javascript:The Good Parts. I try to use console.log() to print something, but I just get TypeError, my code is here:

Function.prototype.method=function(name,func){
    this.prototype[name]=func;
    return this;
}

Function.method('bind',function(that){
    var method=this;
    var slice =Array.prototype.slice;
    var args=slice.apply(arguments,[1]);

    console.log(that);//error: console.log is not a function

    return function(){
        return method.apply(that,args.concat(slice.apply(arguments,[0])));
    };
});

var x=function(){
    return this.value;
}.bind({value:666});

console.log(x());

and the error message is blow:

/home/wz/code/js/c.js:14
    console.log(that);//error: console.log is not a function
            ^

TypeError: console.log is not a function
    at Function.<anonymous> (/home/wz/code/js/c.js:14:13)
    at new Console (console.js:34:23)
    at console.js:100:18
    at NativeModule.compile (bootstrap_node.js:497:7)
    at Function.NativeModule.require (bootstrap_node.js:438:18)
    at get (bootstrap_node.js:254:34)
    at Function.<anonymous> (/home/wz/code/js/c.js:14:5)
    at Object.<anonymous> (/home/wz/code/js/c.js:23:3)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)

Shell 已返回1

It is so interesting when I run the snippet in stackoverflow it works as I expected... So it seems that there are some bugs in my native environment?

I try to use fs to save the console.log into file to see what actually it is in my code, I change the code to:

fs=require('fs');
Function.prototype.method=function(name,func){
    this.prototype[name]=func;
    return this;
}

Function.method('bind',function(that){
    var method=this;
    var slice =Array.prototype.slice;
    var args=slice.apply(arguments,[1]);

    fs.writeFile('a.txt',String(console.log));
    //console.log(that);//error: console.log is not a function

    return function(){
        return method.apply(that,args.concat(slice.apply(arguments,[0])));
    };
});

var x=function(){
    return this.value;
}.bind({value:666});

console.log(x());

and in the a.txt:

function (){
        return method.apply(that,args.concat(slice.apply(arguments,[0])));
    }

So amazing that console.log becomes the returned object... I was totally confused. I have tried node 6.9.1 and 4.6.1 and I got the same result. And I use nvm to manage my node version

wangzhe
  • 51
  • 3
  • 1
    Just a note: you don't need to polyfill `bind` like this within node.js - it supports it natively. – James Thorpe Nov 15 '16 at 10:18
  • What is the value of `console` itself? – damd Nov 15 '16 at 10:18
  • @damd I change console.log to console and I got '[object Object]' in a.txt – wangzhe Nov 15 '16 at 10:24
  • @JamesThorpe Thanks for your remind. I am a js newbie, I just type the code in the Book – wangzhe Nov 15 '16 at 10:26
  • Interesting. If I paste your code exactly as above into the node REPL, it works fine. It's only when it's contained within a file that it fails. – James Thorpe Nov 15 '16 at 10:40
  • And if I add an additional `console.log` above the first line, it also works fine within the file. – James Thorpe Nov 15 '16 at 10:41
  • @JamesThorpe Yes, the console.log works fine in the outer scope. It seems that something happened inside the annoymous function. – wangzhe Nov 15 '16 at 10:46
  • But what I'm saying is that by adding another `console.log` right at the start of the file, it also "fixes" the one in the inner scope. It's most strange. – James Thorpe Nov 15 '16 at 10:47
  • @JamesThorpe Oh yes! so weird. – wangzhe Nov 15 '16 at 10:49
  • 1
    Node's initialization of `console` is lazy. At least one manifestation of this issue was fixed in v5/v6 (see https://github.com/nodejs/node/pull/4479). This might be another manifestation of the same issue. – ZachB Sep 03 '17 at 00:24

1 Answers1

0

You override console somewhere in your code. For avoid Monkey patching you can use construction:

console.log = console.log || function(message) { alert(message);};

With this construction you will not override existing functionality, only add new method or proprieties.

galkin
  • 5,264
  • 3
  • 34
  • 51
  • But my whole code is above, I didn't override console. And the console.log in the outer scope can work normally. – wangzhe Nov 15 '16 at 10:36