《每天十分钟》-红宝书第4版-函数

每个函数都是Function类型的实例,而 Function 也有属性和方法,跟其他引用类型一样
几种定义方式

  1. 函数声明
function sum (num1, num2) { 
 return num1 + num2; 
}
  1. 函数表达式
let sum = function(num1, num2) { 
 return num1 + num2; 
};
  1. 构造函数
let sum = new Function("num1", "num2", "return num1 + num2"); // 不推荐

箭头函数
ECMAScript 6 新增了使用胖箭头(=>)语法定义函数表达式的能力。

let arrowSum = (a, b) => { 
 return a + b; 
}; 
let functionExpressionSum = function(a, b) { 
 return a + b; 
}; 
console.log(arrowSum(5, 8)); // 13 
console.log(functionExpressionSum(5, 8)); // 13

如果只有一个参数,那也可以不用括号。只有没有参数,或者多个参数的情况下,才需要使用括号:

let double = (x) => { return 2 * x; }; 
let triple = x => { return 3 * x; };

省略大括号的情况

// 以下两种写法都有效,而且返回相应的值
let double = (x) => { return 2 * x; }; 
let triple = (x) => 3 * x; 
// 可以赋值
let value = {}; 
let setName = (x) => x.name = "Matt"; 
setName(value); 
console.log(value.name); // "Matt" 
// 无效的写法:
let multiply = (a, b) => return a * b;

箭头函数不能使用 arguments、super 和
new.target,也不能用作构造函数。此外,箭头函数也没有 prototype 属性。

函数名
因为函数名就是指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。

function sum(num1, num2) { 
 return num1 + num2; 
} 
console.log(sum(10, 10)); // 20 
let anotherSum = sum; 
console.log(anotherSum(10, 10)); // 20 
sum = null; 
console.log(anotherSum(10, 10)); // 20

ECMAScript 6 的所有函数对象都会暴露一个只读的 name 属性,其中包含关于函数的信息。多数情况下,这个属性中保存的就是一个函数标识符,或者说是一个字符串化的变量名。即使函数没有名称,也会如实显示成空字符串。如果它是使用 Function 构造函数创建的,则会标识成"anonymous":

function foo() {} 
let bar = function() {}; 
let baz = () => {}; 
console.log(foo.name); // foo 
console.log(bar.name); // bar 
console.log(baz.name); // baz 
console.log((() => {}).name); //(空字符串)
console.log((new Function()).name); // anonymous

如果函数是一个获取函数、设置函数,或者使用 bind()实例化,那么标识符前面会加上一个前缀:

function foo() {} 
console.log(foo.bind(null).name); // bound foo 
let dog = { 
 years: 1, 
 get age() { 
 return this.years; 
 }, 
 set age(newAge) { 
 this.years = newAge; 
 } 
} 
let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age'); 
console.log(propertyDescriptor.get.name); // get age 
console.log(propertyDescriptor.set.name); // set age

理解参数

ECMAScript 函数的参数跟大多数其他语言不同。ECMAScript 函数既不关心传入的参数个数,也不关心这些参数的数据类型。定义函数时要接收两个参数,并不意味着调用时就传两个参数。你可以传一个、三个,甚至一个也不传,解释器都不会报错。
之所以会这样,主要是因为 ECMAScript 函数的参数在内部表现为一个数组。函数被调用时总会接收一个数组,但函数并不关心这个数组中包含什么。如果数组中什么也没有,那没问题;如果数组的元素超出了要求,那也没问题。事实上,在使用 function 关键字定义(非箭头)函数时,可以在函数内部访问 arguments 对象,从中取得传进来的每个参数值。
arguments 对象是一个类数组对象(但不是 Array 的实例),因此可以使用中括号语法访问其中的元素(第一个参数是 arguments[0],第二个参数是 arguments[1])。而要确定传进来多少个参数,可以访问 arguments.length 属性。

//在下面的例子中,sayHi()函数的第一个参数叫 name:
function sayHi(name, message) { 
 console.log("Hello " + name + ", " + message); 
} 
//可以通过 arguments[0]取得相同的参数值。因此,把函数重写成不声明参数也可以:
function sayHi() { 
 console.log("Hello " + arguments[0] + ", " + arguments[1]); 
}

箭头函数中的参数
如果函数是使用箭头语法定义的,那么传给函数的参数将不能使用 arguments 关键字访问,而只能通过定义的命名参数访问。

 console.log(arguments[0]); 
} 
foo(5); // 5 
let bar = () => { 
 console.log(arguments[0]); 
}; 
bar(5); // ReferenceError: arguments is not defined

虽然箭头函数中没有 arguments 对象,但可以在包装函数中把它提供给箭头函数:

function foo() { 
 let bar = () => { 
 console.log(arguments[0]); // 5 
 }; 
 bar(); 
} 
foo(5);

注意 ECMAScript 中的所有参数都按值传递的。不可能按引用传递参数。如果把对象作为参数传递,那么传递的值就是这个对象的引用。

和子由渑池怀旧
人生到处知何似,应似飞鸿踏雪泥。
泥上偶然留指爪,鸿飞那复计东西。
老僧已死成新塔,坏壁无由见旧题。
往日崎岖还记否,路人长困蹇驴嘶。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 05:36:09       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 05:36:09       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 05:36:09       58 阅读
  4. Python语言-面向对象

    2024-07-13 05:36:09       69 阅读

热门阅读

  1. 【Scrapy】Scrapy 中间件等级设置规则

    2024-07-13 05:36:09       24 阅读
  2. 智能运维提升企业长期安全防御能力

    2024-07-13 05:36:09       23 阅读
  3. Linux上如何安装ffmpeg视频处理软件

    2024-07-13 05:36:09       25 阅读
  4. Xcode多任务处理指南:释放iOS应用的并发潜能

    2024-07-13 05:36:09       21 阅读
  5. 力扣题解( 最长定差子序列)

    2024-07-13 05:36:09       26 阅读
  6. npm和yarn清理缓存命令

    2024-07-13 05:36:09       21 阅读
  7. C/C++服务器基础(网络、协议、数据库)

    2024-07-13 05:36:09       23 阅读