javascriptnode.jsconsole.logfunction-call

js rewrite prototype.call, but why did "RangeError: Maximum call stack size exceeded" appear


Function.prototype.call = function(point,...arg){
    console.log('ok');
    const key = Symbol('key')
    point[key] = this
    const data = point[key](...arg)
    delete point[key]
    return data
}
function fn(a,b){
    this.sum = a+b
    return a + b
}
const obj = {}
const data = fn.call(obj,3,4)
console.log(data);
console.log(obj);
node:internal/bootstrap/switches/is_main_thread:149
  if (stdout) return stdout;
  ^

RangeError: Maximum call stack size exceeded
    at process.getStdout [as stdout] (node:internal/bootstrap/switches/is_main_thread:149:3)  
    at console.get (node:internal/console/constructor:214:42)
    at console.value (node:internal/console/constructor:340:50)
    at console.log (node:internal/console/constructor:379:61)
    at Function.call (C:\Users\xyk\Desktop\my study\nodejs\node.js中级\23重写call函数.js:2:13)
    at new WriteStream (node:tty:96:14)
    at createWritableStdioStream (node:internal/bootstrap/switches/is_main_thread:53:16)      
    at process.getStdout [as stdout] (node:internal/bootstrap/switches/is_main_thread:150:12) 
    at console.get (node:internal/console/constructor:214:42)
    at console.value (node:internal/console/constructor:340:50)

Node.js v20.12.1

But if you change "prototype.call" to "prototype.Mycall", this problem will not occur

Function.prototype.Mycall = function(point,...arg){
    console.log('ok');
    const key = Symbol('key')
    point[key] = this
    const data = point[key](...arg)
    delete point[key]
    return data
}
function fn(a,b){
    this.sum = a+b
    return a + b
}
const obj = {}
const data = fn.Mycall(obj,3,4)
console.log(data);
console.log(obj);
ok
7
{ sum: 7 }

This question really confuses me

if I delete "console.log()",the problem will disappear. But I want say, for the case of "prototype. Mycall", even if there is "console. log()", no error will be reported


Solution

  • The nodejs console.log implementation uses .call(). Your Function.prototype.call implementation uses console.log(). This means mutual recursion, and causes a stack overflow since there is no base case.

    So: don't mess with builtins!