两种console.log重写方式的差异及失效原因咨询
关于console.log重写两种写法的差异问题
我能理解下面这种console.log重写方式可以正常工作:
(function(c) { console.log = function() { c.apply(console, arguments); } })(console.log);
但下面这种写法无法正常工作,调用console.log时只会得到一个属性列表,我不明白原因:
(function(c) { console.log = function() { c(arguments); } })(console.log);
请问这两种写法的差异是什么?我需要在第二种写法中手动构建参数数组才能使其正常工作。
差异解析
核心问题出在参数的传递方式上:
- 第一种写法用了
c.apply(console, arguments):apply方法的特性是会把第二个参数(这里的arguments是类数组对象)自动展开成独立的单个参数,传给原有的console.log方法(也就是变量c)。比如你调用console.log('a', 123),原方法会接收到'a'和123两个参数,自然能正常输出。 - 第二种写法直接
c(arguments):这里是把arguments这个类数组对象作为唯一一个参数传给原方法,原console.log会把这个对象当成输出内容,所以你看到的是这个对象的属性列表(比如length、索引值等),而不是你实际想输出的参数。
如果要让第二种写法正常工作,需要手动把arguments拆成单个参数,比如用ES6的扩展运算符:
(function(c) { console.log = function() { c(...arguments); } })(console.log);
或者手动将类数组转为数组后传递,本质都是让原方法接收到独立的单个参数,而不是整个arguments对象。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

