共计 2765 个字符,预计需要花费 7 分钟才能阅读完成。
函数的扩大咱们能够从三个方面来理解与意识:
- 参数的默认值
- 箭头函数
- 对于尾调用的优化
参数的默认值
在 ES6
之前,咱们不能间接为函数的参数指定默认值,只能采纳变通的办法。而 ES6
中容许咱们间接为函数的参数设置默认值,通过等号 =
间接在小括号中给参数赋值。
示例:
function log(name, age = 18) {console.log(name, age);
}
console.log('xkd'); // 输入: xkd
console.log('summer', 20); // 输入: summer 20
console.log('mark', ''); // 输入: mark
如果函数带有某一个参数,则示意这个参数变量曾经默认申明,咱们不能够应用 let
或者 const
再次申明这个变量。
function xkd(a = 1) {let a = 2;}
// 报错:SyntaxError: Identifier 'a' has already been declared
还须要留神的是,在应用函数默认参数时,不容许有同名参数:
function week(a, a, b = 100) {/* ... */}
// 报错信息: SyntaxError: Duplicate parameter name not allowed in this context
参数默认值是惰性求值:
let a = 100;
function xkd(sum = a + 1) {console.log(sum);
}
xkd(); // 输入:101
rest 不定参数
ES6
引入 rest
参数,不定参数用来示意不确定参数个数,由 ...
加上一个具名参数标识符组成。
示例:
function add(...values) {
let sum = 0;
for (var val of values) {sum += val;}
return sum;
}
console.log(add(10, 5, 7)); // 输入:22
下面代码的 add
函数是一个求和函数,利用 rest
参数,能够向该函数传入任意数目的参数。
留神 rest
参数只能放在参数组的最初,并且有且只有一个不定参数,这个参数前面不能再有其余参数,否则会报错。
function func(a, ...b, c) {// ...}
// 报错:SyntaxError: Rest parameter must be last formal parameter
如果咱们要应用函数的 length
属性来获取参数的个数,是不包含 rest
参数的。
function func1(a, b){//...}
function func2(a, b, ...c){//...}
console.log(func1.length); // 输入:2
console.log(func2.length); // 输入:2
name 属性
函数的 name
属性,能够用于返回该函数的函数名。
示例:
function xkd() {console.log(xkd.name); // 输入:xkd
}
xkd();
也能够写成:
var xkd = function() {}
console.log(xkd.name); // 输入:xkd
箭头函数
ES6
中容许应用箭头 =>
来定义函数,这样定义的函数叫做箭头函数。箭头函数次要的两点是:它的 this
指向是在它过后定义所在的区域,还一个是它没有一个作用域的晋升。
示例:
var x = function (y) {return y;}
上述函数应用箭头函数来写,能够写成:
var x = y => y;
如果箭头函数不须要参数或须要多个参数,就应用一个圆括号代表参数局部。
示例:
例如上面这个求两数之和的函数:
var sum = function(num1, num2) {return num1 + num2;}
等同于如下所示箭头函数的写法:
var sum = (num1, num2) => num1 + num2;
如果箭头函数的代码块局部多于一条语句,就要应用大括号将它们括起来,并且应用 return
语句返回。
示例:
var sum = (num1, num2) => {return num1 + num2;}
因为大括号被解释为代码块,所以如果箭头函数间接返回一个对象,必须在对象里面加上括号,否则会报错。
示例:
let obj = age => ({name: "xkd", age:age});
箭头函数能够与变量解构联合应用。
示例:
const full = ({first, last}) => first + ' ' + last;
// 等同于
function full(person) {return person.first + ' ' + person.last;}
箭头函数应用时须要留神的一下几个问题:
- 函数体内的
this
对象指向的是定义时所在的对象,而不是应用时所在的对象。 - 不能够当作构造函数,也就是说不能够应用
new
命令。 - 不能够应用
arguments
对象,能够应用rest
参数代替。 - 不能够应用
yield
命令,因而箭头函数不能用作Generator
函数。
对于尾调用的优化
尾调用就是指某个函数的最初一步是调用另一个函数,不适用于内部变量时只保留内层函数的调用帧。
示例:
例如上面这个 func()
函数中的最初一步是调用函数 show()
,这就叫尾调用:
function func(x) {return show(x);
}
如果在调用一个函数之后,还有其余的操作,则不属于尾调用。
留神,尾调用不肯定呈现在函数尾部,只有是最初一步操作即可,例如上面这段代码中:
function func(x) {if (x > 0) {return f1(x)
}
return f2(x);
}
函数 f1
和 f2
都属于尾调用,因为这两个函数调用都是函数 func
的最初一步操作。
在 ES5
中,尾调用的实现是创立一个新的栈帧 stack frame
,将其推入调用栈中示意函数调用。所以每一个未用完的栈帧都会保留在内存中,当调用栈变得过大时会造成程序问题,也就是咱们常说的栈溢出。
ES6
严格模式下,满足以下三个条件,尾调用不再创立新的 stack frame
,而是重用以后 stack frame
:
- 函数不是一个闭包。
- 在函数外部,尾调用是最初一条语句。
- 尾调用的后果作为函数值返回。
示例:
'use strict';
function func(){
// 优化后
return f();}
而以下几种状况不会进行优化:
- 当没有作为函数值返回,不会优化:
function func(){f();
}
- 返回值后还须要做其余操作,也不会优化:
function func(){return 1+f(); // 返回值后还须要做其余操作
};
- 函数调用不在尾部,也不会优化:
function func(){const result = f();
return result;
};
- 调用的函数是一个闭包函数,也不会优化:
function func(){
const a= 1;
const f = () => a // 这是一个闭包函数,函数 f 须要拜访局部变量 a
return f();};
更多链接:https://www.9xkd.com/