函数
每个函数都是Function类型的实例,而Function也有属性和方法,跟其他引用类型一样。函数是对象,函数名就是指向函数对象的指针,而且不一定与函数本身紧密绑定。
函数定义之函数声明式定义
function sum (n1,n2){ return n1+n2; }
函数定义之函数表达式
let sum = function(n1,n2){ return n1+n2; };
函数定义之箭头函数
let sum = (n1,n2)=>{ return n1+n2; };
函数定义之构造函数
let sum = new Function("n1","n2","return n1+n2"); /*这个构造函数接收任意多个字符串参数, 最后一个参数始终会被当成函数体, 而之前的参数都是新函数的参数*/
箭头函数
任何可以使用函数表达式的地方,都可以使用箭头函数。
let sum = (a,b)=>{ return a+b; }; let sum1 = function(a,b){ return a+b; }; //箭头函数适合嵌入函数的场景 let arr = [1,2,3]; console.log(arr.map(function(i) {return i+1;})); console.log(arr.map((i)=>{return i+1;})); //二者结果一样,但是箭头函数更为简洁 //如果只有一个参数,括号可以不用。只有没有参数,或者多个参数的情况下,才使用括号 let double = (x)=>{return 2*x;}; let triple = x => {return 3*x}; //箭头函数也可以不使用大括号,但这样会改变函数的行为。使用大括号就说明包含函数体,可以在一 //个函数中包含多条语句,跟常规函数一样。如果不使用,后面只能有一行代码。 let double = (x)=>{return 2*x;}; let triple = x=>3*x;
箭头函数虽然语法简洁,但也有很多场合不适用。箭头函数不能使用arguments、super、new.target,也不能用作构造函数。此外,箭头函数也没有prototype属性。
箭头函数中的参数
函数是用箭头语法定义的,那么传给函数的参数将不能使用arguments关键字访问,只能通过定义的命名参数访问。
function foo() { console.log(arguments[0]); } foo(5); // 5 let bar = () => { console.log(arguments[0]); }; bar(5); // ReferenceError: arguments is not defined
函数名
一个函数可以有多个名称。
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
默认参数值
在函数定义中的参数后面用=就可以为参数赋一个默认值。
function makeKing(name = 'Henry') { return `King ${name} VIII`; } console.log(makeKing('Louis')); // 'King Louis VIII' console.log(makeKing()); // 'King Henry VIII'
默认参数值不限于原始值或对象类型,也可以使用调用函数返回的值
let romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI']; let ordinality = 0; function getNumerals() { // 每次调用后递增 return romanNumerals[ordinality++]; } function makeKing(name = 'Henry', numerals = getNumerals()) { return `King ${name} ${numerals}`; } console.log(makeKing()); // 'King Henry I' console.log(makeKing('Louis', 'XVI')); // 'King Louis XVI' console.log(makeKing()); // 'King Henry II' console.log(makeKing()); // 'King Henry III'
参数扩展与收集
ES6新增了扩展操作符,使用它可以非常简洁的操作和组合集合数据 。扩展操作符最有用的场景就是函数定义中的参数列表,在这里它可以充分利用这门语言的弱类型及参数长度可变的特点。扩展操作符既可以用于调用函数时传参,也可以用于定义函数参数。
扩展参数
let values = [1, 2, 3, 4]; function getSum() { let sum = 0; for (let i = 0; i < arguments.length; ++i) { sum += arguments[i]; } return sum; } //不使用扩展操作符实现累加 console.log(getSum.apply(null,values)); //使用扩展操作符 console.log(getSum(...values));
收集参数
收集参数的前面如果还有命名参数,则只会收集其余的参数;如果没有则会得到空数组。因为收集参数的结果可变,所以只能把它作为最后一个参数。
function getProduct(...values,lastValue){}//不可以 function ignoreFirst(firstValue,...values){console.log(values)}//可以 ignoreFirst(); // [] ignoreFirst(1); // [] ignoreFirst(1,2); // [2] ignoreFirst(1,2,3); // [2, 3]
函数声明与函数表达式
JavaScript 引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。// 没问题 console.log(sum(10, 10)); function sum(num1, num2) { return num1 + num2; } /*函数声明提升*/ // 会出错 console.log(sum(10, 10)); let sum = function(num1, num2) { return num1 + num2; };