你知道吗?还可以用length获取函数入参的个数

289 阅读4分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

在JavaScript中,函数就是值。JavaScript 中的每个值都有一种类型,那么函数是什么类型呢?你知道【函数表达式】是什么,那么你了解什么是【命名函数表达式】吗?一起来看看吧!


函数的属性

在 JavaScript 中,函数就是对象。你可以把函数想象成可被调用的“行为对象(action object)”,函数不但可以调用,还可以当做对象来处理:增/删属性,按引用传递等。

🎨 示例:假如有以下这样一个函数

function sayHi() {
  console.log("Hi");
}

📖 如果想要获取函数名字应该怎么做呢?

我们上面说了,函数就是对象,对象就有属性,而函数对象就包含了一些便于使用的属性,如以下示例就是要要了函数对象的属性name

image-20211110005059941

除了name,函数还有一个内置属性length,它会返回函数入参的个数。

image-20211110005600821

💥 注:我们之前有提到过Rest参数...👉传送门,它是不会被length计算到的。

image-20211110005900056

除了上面【函数对象】自带的两个属性,我们还可以自定属性。

🎨 如以下示例 ,给函数新增了一个start属性,并且赋值为一个函数,直接gameLoop.start()即可执行这个函数。

image-20211110193712105


应用实例

函数可以自定义属性,有什么实际意义呢?

其实很多知名的 JavaScript 库都充分利用了这个功能,可以利用这个功能,创建一个“主”函数,然后给它附加很多其它“辅助”函数。这样一个库就只会有一个全局变量,可以减少对全局空间的污染,降低了命名冲突的可能性。

例如:lodash 库创建一个 _ 函数,然后为其添加了 _.add_.keyBy 以及其它属性。

所以,一个函数本身可以完成一项有用的工作,还可以在自身的属性中附带许多其他功能。


命名函数表达式

我们已经说过什么是【函数表达式】👉传送门

【函数表达式】示例

let sayHi = function() {
  console.log( "Hello" );
};

📖那么【命名函数表达式(NFE,Named Function Expression)】又是什么呢?

很简单,来看一个示例就明白了

let sayHi = function func(who) {
 console.log(`Hello, ${who}`);
};

可以看到我们在普通函数表达式里,又加了一个名字func,这样它就是一个【命名函数表达式】了。

📖 那么给【函数表达式】加名字的目的又是什么?

回答这个问题之前,我们先来看看一般函数调用自身是怎么写的

let sayHi = function(who) {
  if (who) {
    console.log(`Hello, ${who}`);
  } else {
    sayHi("Guest"); //调用自身
  }
};

在大多数情况下我们这样做并没有什么问题,但是值得注意的是sayHi 的值可能会被函数外部的代码改变。

image-20211110214722385

这段代码,我们把函数sayHi赋值给了welcome,随后修改了sayHi函数,可以发现welcome调用报错了。

这是因为该函数从它的外部词法环境获取 sayHi。没有局部的 sayHi 了,所以使用外部变量。而当调用时,外部的 sayHinull。所以调用就直接报错了。

但是给函数表达式添加了名字之后再来看

image-20211110214957907

可以看到函数正常运行了,这是因为名字 func 是函数局部域的。它不是从外部获取的(而且它对外部也是不可见的)。规范确保它只会引用当前函数。

外部代码仍然有该函数的 sayHiwelcome 变量。而且 func 是一个“内部函数名”,可用于函数在自身内部进行自调用。

🍇 所有综上所述,我们现在可以来回答为什么要给【函数表达式】加名字,因为它有这两个特殊的地方

✅ 它允许函数在内部引用自己。

✅ 它在函数外是不可见的。

注:【命名函数表达式】依然是一个函数表达式。在 function 后面加一个名字 "func" 没有使它成为一个函数声明,因为它仍然是作为赋值表达式中的一部分被创建的。函数依然可以通过 sayHi() 来调用.

这里所讲的“内部名”特性只针对函数表达式,而不是函数声明。对于函数声明,没有用来添加“内部”名的语法。

参考资料:Function object, NFE


🎨【点赞】【关注】不迷路,更多前端干货等你解锁

往期推荐

👉 前端生成二维码和条形码完整方案

👉 不能不知道的15 个JavaScript数组实用技巧

👉 给开发看的UI设计

👉 WebStorm提高工作效率的实用配置