ES6简介
什么是ES6?
ES6泛指从2015年发布的ES2015,到ES2016、ES2017、ES2018等。
由于部分浏览器未完全支持ES6,所以在使用ES6的项目在放到生产环境时需要使用Babel等工具编译以兼容。
ES6常用新增
let、const
let 声明的变量拥有自己的块级作用域,且修复了var声明变量带来的变量提升和for循环var变量泄露,变量覆盖等问题。
const 新增了定义常量
str
ES6新增了字符串模板,在拼接大段字符串时,用反斜杠(`)取代以往的字符串相加的形式,能保留所有空格和换行,使得字符串拼接看起来更加直观,更加优雅。
ES6在String原型上新增了includes()
方法,用于取代传统的只能用indexOf查找包含字符的方法
let str1 = '我是xxx,我喜欢唱、跳、rap、篮球。';
console.log(str1.includes('我')) //true
此外还新增了startsWith()
, endsWith()
, padStart()
,padEnd()
,repeat()
等方法,可方便的用于查找,补全字符串。
arr
数组解构赋值:let [a,b,c] = [1,2,3]
,在声明较多变量时,不用再写很多let(var),且映射关系清晰,且支持赋默认值。
let [a,b,c] = [1,2,3]
console.log(a,b,c); //1 2 3
扩展运算符:let a = [2,3,4]; let b = [...a]
let a = [{"a":"1"},{"b":"2"},{"c":"3"}];
let b = [...a]
console.log(b); //[{"a":"1"},{"b":"2"},{"c":"3"}]
ES6在Array原型上新增了find()
方法,用于取代传统的只能用indexOf查找包含数组项目的方法,且修复了indexOf
查找不到NaN
的bug([NaN].indexOf(NaN) === -1)
,
let arr = [12,23,34,45,56,88,99];
function calc(num){
return num >= 45
}
console.log(arr.find(calc)); // 45执行得到true返回结束,不会继续执行
from:Array.from
方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable
)的对象(包括 ES6 新增的数据结构 Set
和 Map
)。
const items = new Set([1,2,3,4,5,5,5,5,]);
let arr = Array.from(items)
console.log(arr); //[1, 2, 3, 4, 5] 可用于去重
filter:filter
用于对数组进行过滤。
它创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = nums.filter((num) => {
return num > 5;
});
console.log(res); // [6, 7, 8, 9, 10]
此外还新增了copyWithin()
, includes()
, fill()
,flat()
等方法,可方便的用于字符串的查找,补全,转换等。
obj
1.声明方式:
let [apple, orange] = ['red appe', 'yellow orange'];
let myFruits = {apple, orange}; // let myFruits = {apple: 'red appe', orange: 'yellow orange'};
let {keys, values, entries} = Object;
let MyOwnMethods = {keys, values, entries}; // let MyOwnMethods = {keys: keys, values: values, entries: entries}
2.扩展运算符(...)
:
let {apple, orange, ...otherFruits} = {apple: 'red apple', orange: 'yellow orange', grape: 'purple grape', peach: 'sweet peach'};
// otherFruits {grape: 'purple grape', peach: 'sweet peach'}
// 注意: 对象的扩展运算符用在解构赋值时,扩展运算符只能用在最有一个参数(otherFruits后面不能再跟其他参数)
let allFruits = {apple, orange, ...otherFruits};
console.log(allFruits); //{apple: "red apple", orange: "yellow orange", grape: "purple grape", peach: "sweet peach"}
let moreFruits = {watermelon: 'nice watermelon'};
console.log(moreFruits); //{watermelon: "nice watermelon"}
let allFruits2 = {apple, orange, ...otherFruits, ...moreFruits};
console.log(allFruits2); //{apple: "red apple", orange: "yellow orange", grape: "purple grape", peach: "sweet peach", watermelon: "nice watermelon"}
3.super
关键字:ES6在Class类里新增了类似this的关键字super
。同this总是指向当前函数所在的对象不同,super
关键字总是指向当前函数所在对象的原型对象。
4.ES6在Object原型上新增了assign()
方法,用于对象新增属性或者多个对象合并。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
const returnedTarget = Object.assign(target, source1, source2);
console.log(returnedTarget)// {a:1, b:2, c:3}
这个属性可用于对象的浅拷贝,只需要跟一个空对象合并,但只能拷贝对象的可枚举属性,所以不能算是深拷贝。
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
5.ES6在Object原型上新增了getOwnPropertyDescriptors()
方法,此方法增强了ES5中getOwnPropertyDescriptor()
方法,可以获取指定对象所有自身属性的描述对象。
结合defineProperties()
方法,可以完美复制对象,包括复制get
和set
属性。
6.ES6在Object原型上新增了getPrototypeOf()和setPrototypeOf()
方法,用来获取或设置当前对象的prototype
对象。
这个方法存在的意义在于,ES5中获取设置prototype
对像是通过__proto__
属性来实现的,
然而__proto__
属性并不是ES规范中的明文规定的属性,只是浏览器各大产商“私自”加上去的属性,只不过因为适用范围广而被默认使用了,再非浏览器环境中并不一定就可以使用,
所以为了稳妥起见,获取或设置当前对象的prototype
对象时,都应该采用ES6新增的标准用法。
7.ES6在Object原型上还新增了Object.keys()
,Object.values()
,Object.entries()
方法,用来获取对象的所有键、所有值和所有键值对数组。
function
1.箭头函数:箭头函数是ES6核心的升级项之一,箭头函数里没有自己的this,这改变了以往JS函数中最让人难以理解的this运行机制。
箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象。
ES5函数里的this总是指向函数执行时所在的对象,这使得在很多情况下this的指向变得很难理解,尤其是非严格模式情况下,this有时候会指向全局对象,这甚至也可以归结为语言层面的bug之一。
ES6的箭头函数优化了这一点,它的内部没有自己的this,这也就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己this的函数为止,并作为自己的this;
箭头函数不能用作构造函数,因为它没有自己的this,无法实例化;
也是因为箭头函数没有自己的this,所以箭头函数 内也不存在arguments对象。(可以用扩展运算符代替)
2.函数默认赋值:ES6之前,函数的形参是无法给默认值得,只能在函数内部通过变通方法实现。ES6以更简洁更明确的方式进行函数默认赋值。
function es6Fuc (x, y = 'default') {
console.log(x, y);
}
es6Fuc(4) // 4, default
Symbol
Symbol是ES6引入的第七种数据类型。
所有Symbol()生成的值都是独一无二的,可以从根本上解决对象属性太多导致属性名冲突覆盖的问题。
var str1 = Symbol("a");
var str2 = Symbol("a");
console.log(str1 === str2); //false
Set
Set
是ES6新的数据结构,类似数组,但成员的值是唯一的,没有重复的值。
let set= new Set()
set.add(1)
set.add(2)
set.add(2)
set.add(3)
for(let item of set){
console.log(item) //1,2,3
}
let set2 =new Set([1,2,3,3])
[...set2] //1,2,3
在Set
中,两个NaN
时相等的,会去掉重复的NaN
Map
map()
方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map()
方法按照原始数组元素顺序依次处理元素。
const numbers = [4, 9, 16, 25];
function calcFun(num) {
return num.map(Math.sqrt);
}
console.log(calcFun(numbers))
promise
Promise是ES6引入的一个新的对象,他的主要作用是用来解决JS异步机制里,回调机制产生的“回调地狱”。
new Promise((resolve, reject) =>{
// 一段耗时的异步操作
// resolve('成功') // 数据处理完成
reject('失败') // 数据处理出错
}).then(
// .then()的第一个参数是成功(resolve)的回调
(res) => {
console.log(res)// 成功
// console.log(res2)// 成功
},
// 第二个参数是失败(reject)的回调
(err) => {
console.log(err)// 失败
// console.log(err2)// 失败
}
).catch((err)=>{
console.log(err);
})
.then()
是promise的回调,接受两个参数,第一个参数是promise
的resolve
回调,第二个参数是reject
回调;如果不写,只会执行失败回调(reject);另外,它还有另外一个作用:在执行resolve
的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch
方法中。
class
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法。
构造函数的prototype属性,在ES6的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
class Point {
constructor(){
// ...
}
toString(){
// ...
}
toValue(){
// ...
}
}
// 等同于
Point.prototype = {
toString(){},
toValue(){}
};
Object.assign方法可以很方便地一次向类添加多个方法。
class Point {
constructor(){
// ...
}
}
Object.assign(Point.prototype, {
toString(){},
toValue(){}
});
类的内部所有定义的方法,都是不可枚举的
类的属性名,可以采用表达式。
let methodName = "getArea";
class Square{
constructor(length) {
// ...
}
[methodName]() {
// ...
}
}
module、export、import
module、export、import是ES6用来统一前端模块化方案的设计思路和实现方案。
export、import的出现统一了前端模块化的实现方案,整合规范了浏览器/服务端的模块化方法,
之后用来取代传统的AMD/CMD、requireJS、seaJS、commondJS等等一系列前端模块不同的实现方案,使前端模块化更加统一规范,JS也能更加能实现大型的应用程序开发。
import引入的模块是静态加载(编译阶段加载)而不是动态加载(运行时加载)。
import引入export导出的接口值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
先到这,日后更新