当前位置: 首页 > Web前端 > HTML

面试失败-函数前言的length

时间:2023-03-28 16:57:51 HTML

函数能点进这篇文章的应该是因为看了这个面试题。123['toString'].length+123=?本题的初衷可能是调查Number重写了toString方法,传参可以改变numberconsole.log((10).toString())//10console.log((10).toString(2))//1010是一个很实用的知识点,但是几乎所有的人都栽在了函数的长度上,而且这道题本身也存在问题。这大概是很多人第一次听说函数也有length属性吧?本文将为大家详细介绍这个属性,并指出这道面试题的失败之处。在ECMAScript标准中,ES标准确实规定了函数的length属性,也就是函数的形参个数。让我们测试一下:constfun1=()=>{}constfun2=(a)=>{}constfun3=(a,b)=>{}console.log(fun1.length)//0console.log(fun2.length)//1console.log(fun3.length)//2可见普通形参的函数性能正常。形参有几个,函数的长度是一样的。特殊参数不过ES6新增了两个参数:默认参数和剩余参数,看看这两个参数对结果有什么影响。constfun1=(a,b=1)=>{}constfun2=(a,b=1,c)=>{}constfun3=(a,...b)=>{}console.log(fun1.length)//1console.log(fun2.length)//1console.log(fun3.length)//这个在1标准中没有说明,我们只能通过测试得到结果:函数的长度取决于默认参数之前的第一个参数;剩余的参数不计入函数的长度。看到这里,你可能会疑惑,Number原型上的toString方法可以不带参数调用,难道不是默认参数吗?是的,我也很纳闷,这就是这道面试题的失败之处,请往下看。我们上面得到的规则不适用于原生函数。原生函数指的是JS内部定义的函数。当它们打印在控制台上时,函数体显示为[nativecode]console.log(Number.prototype.toString)//?toString(){[nativecode]}console.log(Array.prototype.slice)//?slice(){[nativecode]}它们的长度很奇怪console.log(Number.prototype.toString.length)//1console.log(Array.prototype.slice.length)//2console.log(Array.prototype.map.length)//1console.log(Array.prototype.forEach.length)//1这四个函数都有默认参数,而前两个默认参数是计入length,最后两个不是。原生函数的长度没有统一的规定!除非你亲自测试过这个函数的长度,否则无法推断出是否参与了形式参数的计算。谁会重新测量本机函数的长度?这就是面试题的失败!很多人可能不知道map和forEach还有第二个参数,用来指定回调函数内部的this指针,前提是传入的回调函数不是箭头函数。还有更离谱的现象与函数的长度有关,这里展示一下。nativefunctions的妙用看push和Function的长度console.log(Array.prototype.push.length)//1console.log(Function.length)//1你知道调用时的参数是什么吗Like?Array.prototype.push(...items)Function(p1,p2,…,pn,body)只能说没看懂函数长度的意思?这两种方式的详细介绍参见push和[Function](https://tc39.es/ecma262/multi...)的标准。删除函数的长度在目前的ES标准中,函数的长度是可配置的,然后出现如下bug?constfun=(a,b)=>{}console.log(fun.length)//1deletefun.lengthconsole.log(fun.length)//0备注:在之前的ES版本中,函数的长度为无法配置。结语在我们实际开发中,函数的长度是完全没有用到的。这个属性的设计是没有意义的。请大家看看这篇文章好玩,或者在别人面前装13~如果喜欢或者得到一些启发,欢迎点赞关注,鼓励新人。