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






博观而约取
原文地址:https://www.cnblogs.com/EssMin/p/14524583.html