JS中Function构造器的length属性
length 是js函数对象的一个属性值,该值是指 “该函数有多少个必须要传入的参数”,即形参的个数
es6之前,函数参数不能设置默认参数值,即存在以下情况
function fn1 () {} // length 为 0 function fn1 (a) {} // length 为 1 function fn1 (a,b,c) {} // length 为 3
形参的数量不包括剩余参数个数,仅包括 “第一个具有默认值之前的参数个数”
// rest parameter is not counted 即:不包括剩余参数个数
但是ES6之后,就稍微变得有一些绕了,原因在于 ES6 更新了一个新特性,让函数可以给形参设置默认值
// 这种写法在 ES6 之前是不允许的 function fn1 (a,b = 10) {}
有了这一新特性之后,length 的解释就要修改成这样: length 的值是指函数的第一个具有默认值的形参之前的形参的个数。
function fn2 (a=1,b) {} // 因为 a 为“第一个具有默认值的形参”,而a的前面没有其它形参了,所以 length 为 0 function fn3 (a,b=1,c) {} // b为 “第一个具有默认值的形参”,前面还有a, length 值为 1 function fn4 (a,b,c=1) {} // length 值为 2 function fn5 (a,b=1,c,d=2) {} // length 值为 1 (第一个具有默认值的形参为b,前面只有a)
console.log("function(...args)",(function(...args) {}).length); // function(...args) 0 //解析:函数参数 ...args,无默认值,所以 “第一个具有默认值之前的参数个数” 个数为 0
function fn1 (a,...args) {} // length 值为 1 // ...args 是有默认值的,默认为一个空数组
// 与之对比的是,arguments.length 是函数被调用时实际传参的个数
console.log("fun (1,2,3) :arguments.length",(function(a = 1, b, c) {return arguments.length})(1,2,3)); // fun (1,2,3) :arguments.length 3
function a(x,y,z){ console.log(arguments.length); // 3 }(1,2,3) function b(x,y=2){ console.log(arguments.length) // 3 }(1,2,3) function c(x,y=2){ console.log(arguments.length) // 1 }(1) function d(x,...args){ console.log(arguments.length) // 2 }(1,2) function e(){ console.log(arguments.length) // 4 }(1,2,3,4)
//另外要注意函数在定义时,剩余参数嘛后面就不要再跟其它的参数了,不然会报错
function func(a, ...rest, b) { } //Rest parameter must be last formal parameter
//注意,rest和arguments一起使用时,部分浏览器会报错
function func(...rest) { console.log(rest) console.log(arguments) }
谷歌的控制台不会报错
火狐的会报错
arguments和剩余参数的区别
- arguments是一个伪数组(Array-like)
- 剩余参数是一个真正数组(Array),具有Array.prototype上的所有方法
- arguments上有callee,callee上有caller
//来自MDN官网:Function 构造器本身也是个Function,它的 length 属性值为 1
console.log("MDN:Function.length",Function.length); /* MDN:Function.length 1 */
另外,JS中几个内置的构造函数,也是函数,length属性值为下
Array.length // 1 Number.length // 1 Function.length // 1 String.length // 1 Boolean.length // 1 Object.length // 1 RegExp.length // 2 Date.length // 7
//辨别函数返回值,此例返回函数体,函数体的length不能和对象的属性混淆
var length="outter"; var obj = { length:"inner", exec:function (){ return (function(length){ return function(){ // code } })(this.length); } }; var exec=obj.exec(); console.log(exec.length); // 0 // 解析: 返回的 exec 是一个闭包 function(){...} ,由上面的 function(){}.length 返回 0 ,可知此处也是返回 0
博观而约取