箭头函数
ES6允许使用箭头 =>定义函数
let fn = (a,b) => {
return a + b
}
// 调用函数
console.log(fn(2,3)) // 5
箭头函数简写
(1) 省略小括号,当形参有且只有一个的时候可以省略小括号。
// let add = (n) => {
// console.log(n + n)
// }
// add(3) // 6
// 简写:
let add = n => {
console.log(n + n)
}
add(3) // 6
(2) 省略花括号 { },仅当函数语句只有一条语句时。此时,‘return’ 必须省略,语句的执行结果即是返回值
let pow = n => n * n
console.log(pow(8)) // 64
(3) 箭头函数返回一个对象
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });
箭头函数特性
- this是静态的,this始终指向函数声明时所在作用域下的this的值
- 不能作为构造函数实例化对象
- 不能使用arguments 变量(函数内部的一个特殊的变量,用来保存实参)
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
上面四点中,最重要的是第一点。对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。
普通函数,执行时this应该指向全局对象window,箭头函数导致this总是指向函数定义生效时所在的对象。
箭头函数实际上可以让this指向固定化,绑定this使得它不再可变,这种特性很有利于封装回调函数。
箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments、super、new.target。
箭头函数适用
箭头函数适合与 this 无关的回调: 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调:事件回调, 对象的方法
rest 参数
//es5 普通函数
function foo() {
//打印结果是一个对象
console.log(arguments); //[Arguments] { '0': 1, '1': 2, '2': 3 }
}
foo(1, 2, 3);
//es6 箭头函数
//rest 参数声明的时候放在形参的位置
//rest参数:以...为前缀,例如下面的...args
const fn = (...args) => {
//打印结果为一个数组
console.log(args); //[ 1, 2, 3, 4, 5 ]
}
fn(1, 2, 3, 4, 5)
//rest 参数如果不放在最后面,会报错,这是一种语法规定
const fn = (a,b,...args) => {
//打印结果为一个数组
console.log(args); //[ 3, 4, 5 ]
}
fn(1, 2, 3, 4, 5)
… 扩展运算符能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算
rest 参数是将用逗号分隔的参数序列转化为数组
扩展运算符将一个数组转为用逗号分隔的参数序列,对数组进行解包;
但是 rest 参数声明的时候放在形参的位置
扩展运算符放在实参的位置,就是调用函数的时候去使用
函数参数默认值
ES6允许给函数参数赋值初始值
特性:
可以给形参赋初始值,一般位置要靠后(潜规则)
function add(a,b,c=12){
return a+b+c;
}
let result = add (1,2)
console.log(result) // 15
name 属性
函数的name属性,返回该函数的函数名。
function foo() {}
foo.name // "foo"
这个属性早就被浏览器广泛支持,但是直到 ES6,才将其写入了标准。
需要注意的是,ES6 对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名。
var f = function () {};
// ES5
f.name // ""
// ES6
f.name // "f"
上面代码中,变量f等于一个匿名函数,ES5 和 ES6 的name属性返回的值不一样。
如果将一个具名函数赋值给一个变量,则 ES5 和 ES6 的name属性都返回这个具名函数原本的名字。
Function构造函数返回的函数实例,name属性的值为anonymous。
(new Function).name // "anonymous"
bind返回的函数,name属性值会加上bound前缀。
function foo() {};
foo.bind({}).name // "bound foo"
(function(){}).bind({}).name // "bound "
Function.prototype.toString()
函数实例的toString()方法返回函数代码本身
function /* foo comment */ foo () {}
//以前会省略注释和空格。
foo.toString()
// function foo() {}
// ES2019 对函数实例的toString()方法做出了修改。
// 修改后的toString()方法,明确要求返回一模一样的原始代码。
foo.toString()
// "function /* foo comment */ foo () {}"