Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么在重写console.log时会出现“超过最大调用堆栈大小”?_Javascript - Fatal编程技术网

Javascript 为什么在重写console.log时会出现“超过最大调用堆栈大小”?

Javascript 为什么在重写console.log时会出现“超过最大调用堆栈大小”?,javascript,Javascript,这是密码 function getMilli(){ return new Date().getTime().toString().substr(7,6); } console.log = function(p1, p2, p3, p4, p5, p6){ console.log(getMilli(), p1, p2, p3, p4, p5, p6); } 不知怎的,它确实出现了堆栈溢出错误,但我不明白为什么在这里。。至少我认为我不是在递归地迭代 …嗯,是的,我在做递归的事情。。

这是密码

function getMilli(){
    return new Date().getTime().toString().substr(7,6);
}
console.log = function(p1, p2, p3, p4, p5, p6){
    console.log(getMilli(), p1, p2, p3, p4, p5, p6);
}
不知怎的,它确实出现了堆栈溢出错误,但我不明白为什么在这里。。至少我认为我不是在递归地迭代

…嗯,是的,我在做递归的事情。。。但我不知道怎么做。感谢您的回答和伟大的概念。

您正在递归调用函数console.log。换句话说,您正在console.log中调用console.log

你可能想做的是:

(function(){

    var clog = console.log.bind(console);

    console.log = function(p1, p2, p3, p4, p5, p6){
        clog(getMilli(), p1, p2, p3, p4, p5, p6);
    }

})();

显然,您是从console.log中调用console.log的,因为当您将它重新分配给新函数时,它不会保留到旧函数的链接,为什么要这样做

您想做的是:

console.old_log = console.log;

console.log = function() { 
  var args = Array.prototype.slice.call(arguments);
  args.unshift(getMilli()); 
  console.old_log.apply(console, args)
}

作为对其他有效答案的改进:

避免污染全局范围或任何对象的属性以存储原始console.log。 避免必须指定任意数量的占位符参数,如p1、p2、p3等。 使用闭包存储原始console.log,并删除对任意参数声明的依赖:

console.log = function (log) {
    return function () {
        var args = Array.prototype.slice.call(arguments);
        args.unshift(getMillis()); // Push millis as first argument
        log.apply(console, args);
    };
}(console.log);

看起来我也是无限递归!您从console.log一直调用console.log。因为您是从console.log中调用console.log?这里的是日志异常。。。日志中的日志中的日志…如果可以的话,请避免使用p1、p2、p3等。@AtesGoral:谢谢,是的,我只是为了快速演示而做的:ASDF比我快了28秒。将删除我的答案并编辑你的答案以包含绑定技巧,我发现这在大多数浏览器中都是必要的。虽然我知道这只是为了演示一种快速的方法,但如果你没有用一个名为clog的变量污染全局名称空间,那就更好了。这里肯定有很多事情要做,但这是实现这一目标的最佳方式!谢谢:只是一个问题:您之所以调用var args=Array.prototype.slice.callarguments;是因为要将非数组类型的参数转换为数组,以便可以对数组使用unshift方法?我是新手JavaScript@JanCarloViray没错。这是将参数转换为常规数组的常见模式。我想知道为什么不在没有[call]的情况下使用它?是因为它会覆盖Array.prototype.slice吗?因此,通过使用call,您可以防止它被覆盖?@JanCarloViray slice不是一个静态实用程序方法,而是一个实例方法,也就是说,您首先需要一个数组实例。但是,它也适用于任何类似数组的对象。在这里,我们通过调用Array.prototype.slice并将参数作为作用域对象来模拟arguments.slice。当不带参数调用slice时,它类似于使用slice0调用它,因此它基本上是数组的一个副本。我们正在制作一个常规数组的参数副本。感谢您的贡献,尽管可以通过@AtesGoral查看“答案”以获得更好的实现