共计 1930 个字符,预计需要花费 5 分钟才能阅读完成。
前言
能点进这篇文章的掘友,应该都是因为看了这道面试题吧。
123['toString'].length + 123 = ?
这道题的本意可能是想考查 Number
重写了 toString
办法,能够通过传递参数扭转数字的进制
console.log((10).toString()) // 10
console.log((10).toString(2)) // 1010
这算一个蛮实用的知识点,但简直所有的人,都是栽在了函数的 length
上,而且这道题自身,也存在着问题。
很多人应该是第一次据说,函数还有个 length
属性?
本文会向你具体介绍这个属性,并指出这道面试题的败笔。
ES 规范
在 ECMAScript 规范中,的确规定了函数的 length
属性,是函数形参的个数。
咱们来测试一下:
const fun1 = () => {}
const fun2 = (a) => {}
const fun3 = (a, b) => {}
console.log(fun1.length) // 0
console.log(fun2.length) // 1
console.log(fun3.length) // 2
能够看出,一般形参的函数体现是失常的,有几个形参,函数的长度就是多少。
非凡参数
然而,ES6 新增了两种参数:默认参数 和残余参数,看看这两种参数对后果的影响。
const fun1 = (a, b = 1) => {}
const fun2 = (a, b = 1, c) => {}
const fun3 = (a, ...b) => {}
console.log(fun1.length) // 1
console.log(fun2.length) // 1
console.log(fun3.length) // 1
规范中对此并未阐明,咱们只能通过测试得出后果:
函数的长度取决于第一个默认参数之前的参数;残余参数不计算在函数的长度中。
看到这你或者会纳闷,Number
原型上的 toString
办法能够不加参数调用的呀,不算默认参数吗?
对,我也很纳闷,这就是这道面试题的败笔了,请接着往下看。
败笔
下面咱们得出的规定,并不实用于原生函数。
原生函数指的就是 JS 外部本人定义的函数,它们在控制台打印时函数体显示为 [native code]
console.log(Number.prototype.toString) // ƒ toString() { [native code] }
console.log(Array.prototype.slice) // ƒ slice() { [native code] }
而它们的 length
就很奇怪了
console.log(Number.prototype.toString.length) // 1
console.log(Array.prototype.slice.length) // 2
console.log(Array.prototype.map.length) // 1
console.log(Array.prototype.forEach.length) // 1
这四个函数都是有 默认参数 的,而前两个将默认参数算进了 length
中,后两个则不算。
原生函数的长度并没有对立的规定!除非你亲自测试过这个函数的 length
,不然形参是否参加计算,基本无从推断。
谁会没事把原生函数的长度都测一遍啊,这就是面试题的败笔!
可能许多人不晓得 map 和 forEach 还有第二个参数,用以指定回调函数外部的 this 指向,前提是传入的回调函数不是箭头函数。
离谱
无关函数的长度,还有更为离谱的景象,在此展现。
原生函数中的奇葩
看看 push
与 Function
这两个函数的长度
console.log(Array.prototype.push.length) // 1
console.log(Function.length) // 1
你晓得它们调用时的参数是什么样的吗?
Array.prototype.push (…items)
Function (p1, p2, … , pn, body)
只能说,我不了解函数的 length
有何意义?
无关这两个办法能够详见 push 与 [Function](https://tc39.es/ecma262/multi…
) 的规范。
删除函数的 length
目前的 ES 规范中,函数的长度是可配置的,而后就呈现了上面的 bug?
const fun = (a, b) => {}
console.log(fun.length) // 1
delete fun.length
console.log(fun.length) // 0
备注:在之前的 ES 版本中,函数的长度是不可配置的。
结语
在咱们的理论开发中,基本用不到函数的 length
,这个属性设计的毫无意义,本文就请当个乐子看看就好了,或者在别人背后装个 13~
如果喜爱或者有所启发,欢送点赞关注,激励一下新人作者。