关于javascript:面试败笔-函数的length

2次阅读

共计 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 指向,前提是传入的回调函数不是箭头函数。

离谱

无关函数的长度,还有更为离谱的景象,在此展现。

原生函数中的奇葩

看看 pushFunction 这两个函数的长度

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~

如果喜爱或者有所启发,欢送点赞关注,激励一下新人作者。

正文完
 0