目录
一、介绍
ECMAScript 6.0(以下简称ES6,ES2015)是JavaScript语言的下一代标准,于2015年6月正式发布。使JavaScript语言可以用来编写复杂的大型应用程序。
二、新特性
2.1 let 和 const 命令
var | 1、变量提升; 2、可以重复声明,覆盖; |
let | 1、声明变量,没有变量提升; 2、块作用域; 3、相同作用域内不能重复声明; |
作用:1、for循环是一个经典的例子: 2、不会污染全局变量。 在知道变量值需要被修改的情况下使用let | |
const | 1、声明常量,一旦被声明,无法修改; 2、可以修改常量对象内部中的属性; 3、不能重复声明; |
默认情况下使用const |
2.2 es6的模板字符串
比较 | |
传统字符串 | 1、使用单引号 '' 或者双引号 "" ; 2、多行文本需拼接,直接插入换行符会报错。 |
模版字符串 | 1、使用反单引号(backquote) `` ; 2、可以插入表达式:`${express}`,express可以是任意常量、变量、函数调用,前后可有任意的其他合法字符; 3、可以多行文本,允许直接插入换行符。 |
2.3 增强的函数
1、带参数默认值的函数
ES5 | ES6 |
函数add需要两个参数,函数中先判断a、b两个参数是否有赋值,若没有,则默认值为10、20. | 1、可以看出哪些参数是可以省略的; 2、利于代码优化; |
2、默认的表达式也可以是一个函数
function add( a, b = getVal(5) ){
return a + b;
}
function getVal(val){
return val + 5;
}
console.log(add(10)); // 20
3、 剩余参数
把多个独立的合并到一个数组中
// 剩余参数:由三个点... 和一个紧跟着的具名参数指定 ...keys
function pick(obj, ...keys){
// ...keys 解决了arguments的问题,keys可以任意命名,建议根据需求命名
// arguments 是伪数组
let result = Object.create(null);
for (let index = 0; index < keys.length; index++) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
let book = {
title: '前端',
author: 'XXX',
year: 2023
}
let bookData = pick(book,'title','author');
console.log(bookData); // {title:'前端',author:'XXX'}
4、 扩展运算符
将一个数组分割,并将各个项作为分离的参数传给函数
// es5 处理数组中的最大值,使用apply
const arr = [10,20,30,33,45,5,100,90];
console.log(Math.max.apply(null,arr)); //100
// es6 使用扩展运算符
console.log(Math.max(...arr)); // 100
5、箭头函数
使用 => 来定义,function(){} 等价于 ()=>{}
let add = (a,b)=>{
return a + b;
}
// 简写
// let add = (a,b) => (a + b);
console.log(add(10,20)); // 30
// 仅有一个参数时可简写
let add1 = val => {
return val + 5;
}
// 还可简写为
// let add1 = val => (val+5);
// let add1 = val => val; // 5
console.log(add1(10)); // 15
箭头函数的this指向:
箭头函数没有自己的this对象,内部的this值只能通过查找作用域链来确定。es5中的this指向取决于调用该函数的上下文对象。
注意事项:
1)如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 10;
var add = (a,b) => a + b;
2) 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return
语句返回。
var add = (a,b) => {return a + b;}
3)由于大括号被解释为代码块,如果箭头函数返回的是一个对象,必须在对象外面加上括号,否则报错。
// 报错
let getTemp = id => {id: id, name: "张三"};
// 不报错
let getTemp = id => ({id: id, name: "张三"})
4) 不可以使用arguments
对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
5)不能使用new关键字来实例化对象,箭头函数不是一个对象,其实就是一个语法糖。
2.4 扩展的字符串、对象、数组功能
1、扩展的对象功能
1)es6直接写入变量和函数,作为对象的属性和方法
const name = '张三', age = 20;
const person = {
name, //等价于name: name
age,
sayName: function(){
console.log(this.name);
}
}
person.sayName(); // 张三
2)对象的方法
方法一: is(),比较两个值是否严格相等,与严格比较运算符 === 的行为基本一致。
console.log(Object.is(NaN,NaN)); // true
console.log(NaN === NaN); // false
方法二: 对象的合并: Object.assign(target,obj1,obj2,......),第一个参数是目标对象,后面的参数都是源对象,若有同名属性,则后面的属性会覆盖前面的属性。
// 浅拷贝,返回合并之后的新对象
let newObj = Object.assign({},{name:'张三'},{age:20});
console.log(newObj); //{name: '张三', age: 20}
如果源对象某个属性的值是个对象,那么目标对象拷贝得到的是这个对象的引用,源对象的任何变化都会反映到目标对象上面。
2、扩展的数组功能
方法一:from() 将伪数组转换成真正的数组
function add(){
console.log(arguments); // 伪数组,缺少数组方法
// es5 转换
let arr = [].slice.call(arguments);
console.log(arr);
//es6
let arrEs6 = Array.from(arguments);
console.log(arrEs6);
}
add(1,2,3)
主要应用于遍历dom,例:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
let lis = document.querySelectorAll('li');
console.log(Array.from(lis));
// 扩展运算符 将伪数组转换成真正的数组
console.log([...lis]);
from() 方法还可接收一个函数作为第二个参数,用来对每个元素进行处理,将处理后的值放入返回的数组。
let liCons = Array.from(lis, ele => ele.textContent);
console.log(liCons); //['1', '2', '3', '4']
还可以应用于判断字符串的长度:
let str = "我爱你,中国!";
console.log(Array.from(str).length); // 7
方法二: of() 将任意的数据类型,转换成数组
console.log(Array.of(3,11,20,[1,2,3],{id:123})); // [3, 11, 20, [1,2,3], {id:123}]
方法三:copyWithin() 在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。
接收三个参数:
参数一: target --必需,从目标位置开始替换数据,如果为负值,表示倒数。
参数二: start --可选,从该位置开始读取数据,默认为0,负值,表示从末尾开始计算
参数三: end --可选,到该位置停止读取数据,默认等于数组长度,负值,表示从末尾开始计算
// 表示从位置3开始到数组结尾(8、9、10),替换从0号位置开始的数值(1、2、3)
console.log([1,2,3,8,9,10].copyWithin(0,3)); //[8, 9, 10, 8, 9, 10]
方法四:find() 找出第一个符合条件的数组成员,如果没有符合条件的成员,则返回undefined
。
let num = [1,2,-10,-20,9,2].find(n => n<0);
console.log(num); // -10
方法五:findIndex() 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
。
let index = [1,2,-10,-20,9,2].findIndex(n => n<0);
console.log(index); // 2
方法六: keys() 对键名的遍历
for(let index of ['a','b'].keys()){
console.log(index);
}
// 0
// 1
方法七: values() 对值的遍历
for(let ele of ['a','b'].values()){
console.log(ele);
}
// a
// b
方法八: entries() 对键值对的遍历
for(let [index,ele] of ['a','b'].entries()){
console.log(index,ele);
}
// 0 'a'
// 1 'b'
以上方法皆返回一个遍历器,可以使用for...of循环进行遍历。
方法九: includes() 返回一个布尔值,表示某个数组是否包含给定的值,有返回true,没有返回false
console.log([1,2,3].includes(2)); // true
2.5 解构赋值
是对赋值运算符的一种扩展,针对数组和对象来进行操作,优点是代码书写上简洁易读。
1) 对象解构赋值
let node = {
type: 'iden',
name: 'foo'
}
// 完全解构
let {type,name} = node;
console.log(type,name); //iden foo
let obj = {
a: {
name: '詹丹'
},
b:[],
c:'hello world'
}
// 不完全解构,可忽略
let {a} = obj;
console.log(a); // {name: '詹丹'}
// 搭配使用剩余运算符
let {a,...res} = obj;
console.log(res); // {b:[],c:"hello world"}
// 默认值
let {a, b=30} = {a:20}
console.log(a,b); //20 30
2)数组的解构赋值
// 完全解构
let [a, b, c] = [1, 2, 3];
console.log(a,b,c); //1 2 3
// 嵌套数组解构
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo, bar, baz); //1 2 3
let [, , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
// 如果解构不成功,变量的值就等于undefined
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
// 不完全解构
let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
如果等号的右边不是可遍历的结构,将会报错。
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
// Uncaught SyntaxError: Identifier 'foo' has already been declared