js自定义console.log完全不理解,求大神

function log(){
    console.log.apply(console, arguments);
};

这句中我理解该是,让console指向console.log,为什么要让console这个对象指向它自己的一个方法呢?还有后边这个arguments是传入给console的应该,但是console(arguments),也不是console.log(arguments)啊,完全看不懂,急哭,求大神帮帮忙

阅读 15.2k
7 个回答
function log(){
    console.log.apply(console, arguments);
};

arguments为log函数调用时实际传递给log函数的参数列表,是一个类数组对象,可以获取其长度及通过下标获取log函数实际调用时接收到的各个参数
apply方法为Function函数对象的方法,其第一个参数指定了函数对象的的执行上下文,也就是我们函数调用时的this变量的指向,apply第2个参数为一个数组,为传递给函数对象的运行参数

上面代码这样写的一个目的就是为了解决log方法被调用时实际传入参数不确定的问题,参数的不确定导致你方法通过常规的console.log方法来输出日志

类似的还有一个call方法,和apply方法的区别为参数是一个一个参入而不是以数组的方法打包传入,在你有确定的参数个数时使用

arguments是传给log()函数的实参。比如你调用log('hello', 'world'),那么arguments就是['hello', 'world']

console.log.apply(console, arguments)这个主要是用来把arguments中的每个参数当作实参传递给console.log()的。如果直接像下面这样调用:

console.log(arguments)

那么会将arguments当作一个数组打印,而不是将其中的每一项作为参数传递给console.log()。也就是说,它的效果是:

console.log(['hello', 'world']) // 打印数组的内容['hello', 'world']

而我们希望的是:

console.log('hello', 'world') // 这时才是打印字符串hello world

apply就正好可以实现这种需求

其中 apply() 是改变 this 的指向问题,这里是让 this 指向 console,对于后面的 arguments 则是一个类数组对象,表示函数接受的参数,而 apply() 可以接受一个数组,和 apply() 类似的还有一个叫 call() 的函数,而在这里为什么不用 call() 是因为 log() 传入的参数个数是不确定的,因为 call() 一般用在参数个数确定的情况下,至于 apply()call() 的作用则是完全一样,就是改变函数体内 this 的指向问题,指向 apply()call() 的第一个参数所代表的对象,也就是这里的 console 对象。

//比如console.log方法是这样的话:
var console.log = function (){
    //它带了一个this,这个this就是指向console对象!
    var _this = this;
}

console.log.apply(console, arguments)的意思是:
让上面声明的那个log中的this由原来的指向切换到新的指向,即参数中的那个console——这句话是题主理解的重点咯~请看下面展开:
如果不将第一个参数设置成console,你可以设置成window试试,于是上面的调用就变成console.log.apply(window, arguments),那么因为log.apply中的this是指向第一个参数的即window`的,也就是:
[纠正]因为console内部机制,用window调用是不合法的,只能用console自己调用!
这是要这样写console.log.apply(console, arguments)的原因。

而通过apply的调用,第二个目的是为了达到可以一次接受一个参数arguments列表。

理解误区:
console.log.apply(console, arguments)等同console.log(arguments)而不是console(arguments),且此时的console.log是被apply处理过的,可以一次接受若干参数。
表轻易的理解ax.apply(bx, arguments) ==> bx(arguments)

2021年来回答一下,这里应该是2016年还没有普及参数解构这种语法
2021年可以这样写

function log(){
    console.log(...arguments);
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题