探究一些 JavaScript 函数似真似假的特点。
函数对象是存在 name
属性的,如期字面意思一般,该字段会返回函数名称:
function add(a, b) {
return a + b;
}
console.log(add.name); // "add"
可能想说,这玩意有什么用,那不就函数对象的名称嘛,说穿了,那就是一个变量的名称,而然多数情况下,变量名称是给开发者看的,只要开发者认得出来,那管它叫什么名字呢,重点是值。
确实是说,没有什么实际用途,而且不是所有时候,name
都会展示变量名称,列举一个场景:
const fn = add;
console.log(fn.name); // "add"
虽然这有点意思,但是 name
依旧属于可读不可写的属性。
const fn = add;
console.log(fn.name); // "add"
fn.name = "fn";
console.log(fn.name); // "add"
函数对象还真存在 length
属性,标明了该函数的参数列表长度。比如:
function add(a, b) {
return a + b;
}
console.log(add.length); // 2
挺简单粗暴的,这就完了吗,并不是。有一条规则,length
属性反应的是必要参数数量。
什么时候,函数参数会是非必要参数呢?那就得试试 ES6 新增的默认参数与剩余参数1了:
function add(a, b = a) {
return a + b;
}
console.log(add.length); // 1
function sum(...nums) {
return nums.reduce((r, v) => r + v)
}
console.log(sum.length); // 0
对默认参数额外做一点补充,当一个函数存在默认参数时,其 length
属性的计算是从第一个默认参数开始,就停止了。
{
function add(a = 0, b = a) {
return a + b;
}
console.log(add.length); // 0
}
{
// 不符合标准的写法,此处只为演示效果
function add(a, b = a, c) {
return a + b;
}
console.log(add.length); // 1
}
与 name
一样,存在只读规则,不再赘述。可以得到结论,还是不靠谱,属于考点,但不实用。
刚看到这玩意的时候,打开了 VSCode,开始编辑 index.ts
,一段段红线让我陷入的沉思,谁在和我瞎扯呢,就否定了这个观点的存在。
但是慢着,谁要你使用 TypeScript 了,这么好玩的事情当然得上 JavaScript 啦。
首先说明,这个是可以存在的,哪怕在平日当中写不出来。
function add(a, a) {
return a + a;
}
console.log(add(10, 20)); // 40
其表现如同 var
声明变量一般,后者覆盖前者,可以模拟一下函数参数赋值过程:
var a = 10;
var a = 20;
console.log(a); // 20
其次,该形式只能存在于非严格模式当中:
"use strict"
// Duplicate parameter name not allowed in this context
function add(a, a) {
return a + a;
}
这种属于低级错误,作为题目考核,纯粹就是玩一手,在 TypeScript、ESLint 与 IDE 横行的时代,想写出来都很难。
-END-
也被称为收集参数(我更习惯如此)、rest 参数(《ES6 入门》),此处选择使用 MDN 上的翻译名:剩余参数。 ↩︎