面试中遇到过的一道面试题:如何封装一个console.log()
?
当时实在不理解为什么要封装这个,为什么不直接拿来用,可能是为了考察apply
和arguments
?
回来之后问了度娘,得到了部分的答案:
在开发的过程中,可能会因为debug,加入
console.log()
这样的语句,在控制台输出内容,方便debug,但是往往上生产就忘记删除,导致信息泄露...
当然,它的功能可能不仅仅于此,还有其他功能待挖掘,今后再做补充吧。
仅仅是封装这个功能很简单,用到了apply()
:
function logInfo(){
console.log.apply(console,arguments);
}
就可以直接拿来用了,为什么要使apply
再指向console
呢?
是因为我们其实还是要使用console.log()
这个方法来做输出,只不过每次输出的内容不一样,这里的内容就是arguments
。
很明显在这个封装的方法中传入的参数是不确定的,并不确定你要在控制台输出什么东西,所以传入的参数就无法预知,这也就是call()
和apply()
的区别,详情另起一篇文章,所以这个时候就要用到arguments
对象了,官方的说法:
arguments
是一个对应于传递给函数的参数的类数组对象。
arguments
对象不是一个Array
。它类似于Array
,但除了length属性和索引元素之外没有任何Array
属性。
arguments
在封装的方法中,是作为一个参数传递给了log()
方法,例如:logInfo('hello','world')
,那么arguments
就是['hello','world']
,使用console.log.apply(console,arguments)
主要是用来把arguments
中的每个参数都作为实参来传递给console.log()
的。
如果像下面这样直接调用:
function logInfo() {
console.log(arguments);
}
logInfo(1, 2, 3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
那么会将arguments
作为一个数组进行打印输出,而不是将其中的每一项作为参数传递给console.log()
进行输出,很明显,上例的结果并不是我们想要的,我们想要的结果是这样的1,2 3
,而apply()
就正好可以实现这个需求。
回顾下apply()
的知识:
-
语法:
func.apply(thisArg,[argsArray])
-
thisArg
在 func 函数运行时使用的 this 值。 -
argsArray
一个数组或者类数组对象,其中的数组元素将作为单独的参数传给
func函数
。
这也就是为什么apply()
能实现这个需求的原因,它会将数组(即封装函数中的arguments
)中的每个元素都作为参数传递给函数(也就是console.log()
)。
网友评论