1. 函数参数默认值
在ES5中我们想给函数的参数设置默认值通常是通过短路表达式来操作:
function log(x, y) { y = y || 'World'; console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello World
ES6则允许为函数的参数设置默认值,即直接写在参数定义的后面。
function log(x, y = 'World') { console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello
2. rest参数
形式为“...变量名”,用于获取函数的多余参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。注意,rest参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10
3. 扩展运算符(spread)
是三个点(…)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列,该运算符主要用于函数调用。
function add(x, y) { return x + y; } var numbers = [4, 38]; add(...numbers) // 42
这里在举个例子,我们先从Math.max()函数说起,Math.max后面可以接任意个参数,最后返回所有参数中的最大值。比如
alert(Math.max(5,8)) //8 alert(Math.max(5,7,9,3,1,6)) //9
但是在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1] alert(Math.max(arr)) // 这样却是不行的。一定要这样写 function getMax(arr){ var arrLen=arr.length; for(var i=0,ret=arr[0];i<arrLen;i++){ ret=Math.max(ret,arr[i]); } return ret; }
这样写麻烦而且低效。如果用 apply呢,看代码:
function getMax2(arr){ return Math.max.apply(null,arr); }
那如果使用ES6呢
function getMax3(arr){ return Math.max(...arr); } getMax3(arr) //9
4. 箭头函数
在箭头函数出现之前,每个新定义的函数都有它自己的 this
值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被作为“对象方法”调用则为基础对象等),寻找This
的指向更是令人厌烦。所以在ES6引入了箭头函数,其优势更简短的函数并且不绑定this。箭头函数不会创建自己的
this,它只会从自己的作用域链的上一层继承this。
至于什么说是箭头函数呢?因为他是由箭头定义的啊,O(∩_∩)O。
(1) 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
(2) 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
箭头函数的基本语法:
(参数1, 参数2, …, 参数N) => { 函数声明 } //相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; } (参数1, 参数2, …, 参数N) => 表达式(单一) // 当只有一个参数时,圆括号是可选的: (单一参数) => {函数声明} 单一参数 => {函数声明}
v => v;
//上面的箭头函数等同于:
function(v) {
return v;
};
// 没有参数的函数应该写成一对圆括号。 () => {函数声明}
高级语法
//加括号的函数体返回对象字面表达式: 参数=> ({foo: bar}) //支持剩余参数和默认参数 (参数1, 参数2, ...rest) => {函数声明} (参数1 = 默认值1,参数2, …, 参数N = 默认值N) => {函数声明} //同样支持参数列表解构 let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
箭头函数可以有一个“简写体”或常见的“块体”。
在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return
语句。
var func = x => x * x; // 简写函数 省略return var func = (x, y) => { return x + y; }; //常规编写 明确的返回值
返回对象字面量节
记住用params => {object:literal}
这种简单的语法返回对象字面量是行不通的。
var func = () => { foo: 1 }; // Calling func() returns undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name
这是因为花括号({}
)里面的代码被解析为一系列语句(即 foo
被认为是一个标签,而非对象字面量的组成部分)。
所以,记得用圆括号把对象字面量包起来:
var func = () => ({foo: 1});
箭头函数内定义的变量及其作用域
this指向问题
注意:
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。通过 call 或 apply 调用由于 箭头函数没有自己的this指针,通过 call()
或 apply()
方法改变this指向。
上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到100毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42。即箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。