1.带参数默认值的函数
为了防止在调用函数时忘记传入参数,通常会给参数一个默认值。
//es5写法
function add(a, b) {
a = a || 10;
b = b || 20;
return a + b;
}
console.log(add());//30
//es6写法
function add(a, b = 20) {
return a + b;
}
console.log(add(30));//50
2.参数的默认值也可以是一个带返回值的函数
function add(a, b = getVal(5)) {
return a + b;
}
function getVal(val) {
return val + 5;
}
console.log(add(10));//20
3.剩余参数
剩余参数: 由三个点...和一个紧跟着的具名参数指定 ...keys
解决问题: 解决arguments伪数组问题
注意: 剩余参数必须写在参数列表的最后,否则会报错
//es5使用arguments
function pick(obj) {
let result = Object.create(null);
console.log(arguments);
/*
Arguments(4) [{…}, "title", "year", "author", callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: {title: "es6教程", author: "tom", year: 2020}
1: "title"
2: "year"
3: "author"
length: 4
由于Arguments本身原因使得索引要从1开始
*/
for(let i = 1;i < arguments.length;i++){
result[arguments[i]] = obj[arguments[i]]
}
return result;
}
let book = {
title:'es6教程',
author:'tom',
year:2020
}
let bookData = pick(book,'title','year','author');
console.log(bookData);//{title: "es6教程", year: 2020, author: "tom"}
//es6剩余参数写法
function pick(obj, ...keys) {
// ...keys 解决了arguments 的问题
let result = Object.create(null);
console.log(keys);//["title", "year", "author"]
for (let i = 0; i < keys.length; i++) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
let book = {
title: 'es6教程',
author: 'tom',
year: 2020
}
let bookData = pick(book, 'title', 'year', 'author');
console.log(bookData);//{title: "es6教程", year: 2020, author: "tom"}
4.扩展运算符
剩余运算符: 把多个独立的项合并到一个数组中
扩展运算符: 也是使用...,将一个数组或对象中的每一项分割,并将各个项作为分离的参数传给函数
1.处理数组中的最大值
const arr = [5, 13, 54, 46, 29, 78];
//es5处理方法,难以理解
console.log(Math.max.apply(null, arr));//78
//es6扩展运算符处理
console.log(Math.max(...arr));//78
2.数组合并
const arr1 = [1, 3, 5];
const arr2 = [2, 4, 6];
const arr = [...arr1, ...arr2];
console.log(arr);//[1, 3, 5, 2, 4, 6]
3.对象合并
const obj1 = {
name: 'tom',
age: 20
};
const obj2 = {
id: '002',
name: 'jerry'
};
const obj = {...obj1, ...obj2};
console.log(obj);//{name: "jerry", age: 20, id: "002"}
可以看到上面两个对象进行了合并,同时可以看到输出的name是jerry而不是tom,说明当多个对象合并时,如果这些对象中有相同的属性名,后面的值会把前面的值覆盖。
5.箭头函数
es6中使用=>来定义函数,function(){}等同于()=>{}
//es5写法
let add = function (a, b) {
return a + b;
}
//es6写法
//多个参数,以下三种写法和上面效果一样
let add = (a, b)=>{return a+b};
let add = (a, b) => (a + b);
let add = (a, b) => a + b;
//只有一个参数
let fn = a => a + 5;
console.log(fn(5));//10
//无参
let fn = () => 'hello world' + 123;
console.log(fn());//hello world123
//返回一个对象
let getObj = id => ({id: id, name: "tom"});
let obj = getObj(1);
console.log(obj);
//返回一个函数
let fn = (() => {
return () => {
console.log('hello es6');
}
})();
fn()
总结: 当只有一个参数时左边的()可以省略,但是当无参时左边的()不能省略,当返回的是一个对象时必须在返回的对象外加上()
箭头函数中的this指向问题
es5中this指向取决于调用该函数的上下文对象
es6的箭头函数中没有this指向,箭头函数内部this值只能通过查找作用域链来确定,一旦使用箭头函数,当前就不存在作用域链,它会继续向上层的作用域链查找。
//es5写法
let PageHandle = {
id: 123,
init: function () {
document.addEventListener('click', function (e) {
console.log(this);//当前this指向document
this.doSomeThing(e.type);//this.doSomeThing is not a function
})
},
doSomeThing: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`);
}
};
PageHandle.init();
当前this指向发生改变,找不到doSomeThing方法,es5解决办法,使用bind()绑定当前对象:
let PageHandle = {
id: 123,
init: function () {
document.addEventListener('click', function (e) {
console.log(this);//当前this指向PageHandle
this.doSomeThing(e.type);
}.bind(this))
},
doSomeThing: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`);//事件类型:click,当前id:123
}
};
PageHandle.init();
bind()虽然解决了问题,但是它不好理解。下面使用es6箭头函数来解决这个问题:
let PageHandle = {
id: 123,
init: function () {
document.addEventListener('click', (e) => {
console.log(this);//当前this指向PageHandle
this.doSomeThing(e.type);
})
},
doSomeThing: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`);//事件类型:click,当前id:123
}
};
PageHandle.init();
使用箭头函数的注意事项
1.箭头函数内部没有arguments
let getVal = (a, b) => {
console.log(arguments);//arguments is not defined
return a + b;
};
console.log(getVal(1, 3));
2.箭头函数不能使用new关键字来实例化对象
function函数也是一个对象,但是箭头函数不是一个对象,它其实就是一个语法糖。
let Person = () => {
};
let p = new Person();//Person is not a constructor