ES6是之前所学的ES5的版本升级,对于es6来说,想要在浏览器上直接运行是很难的,因为es6中有些代码的不兼容浏览器,无法显示其效果,但是在nodejs运行环境下是完全兼容的,而在js中做ajax、dom必须将代码运行在浏览器中,所以需要安装nodejs环境来运行es6。
在ES5中使用dom驱动,使用的是真实的dom,先有的dom再有js ; 而在ES6中的dom为虚拟dom,即通过js来生成dom。
ES6提供了简洁的语法和新的特性:迭代器、Map、Set、Promise、箭头函数、异步函数等等
- 变量的声明:在es6中新增了let、const来声明变量
在es5中,使用var声明的变量只用【函数作用域】和【全局作用域】,
在es6中,使用let、const声明的变量只在【{ }块级作用域】中使用
const是进行声明一个只读常量,声明变量的同时必须初始化,且后期常量值不能改变
//ES5:
var date = new Date();
function say(){
console.log(date); //undefined
if(false){
var date = '2020-01-01';
console.log(date);
}
}
//等价于==> var声明的变量只有【函数作用域】和【全局作用域】/ 之前说过的变量的提升
var date = new Date();
function say(){
var date; //变量的提升
console.log(date); //undefined
if(false){
date = '2020-01-01';
console.log(date);
}
}
//ES6:
function say(){
let date = new Date();
console.log(date); //new Date()产生的当前时间
if(false){
let date = '2020-01-01'; //不允许变量的提升
console.log(date);
}
}
ES5 与 ES6 变量声明区别:
声明方式 变量提升 暂时性死区 重复声明 块级作用域
var 允许 不存在 允许 不存在
let 不允许 存在 不允许 存在
const 不允许 存在 不允许 存在
暂时性死区:表示在这个变量声明之前,都不可以操作该变量
2. 解构(模式匹配)
ES6中,允许按照一定的模式,从数组或对象中提取值,并且对其进行一些操作。
2.1 数组解构
数组赋值:在ES6之前,对于数组或对象中属性赋值,需要单个进行赋值,而在ES6中可以通过解构方式进行赋值。
//例:
let [name,age,gender] = ['oh',10,'male'];
console.log(name,age,gender); //oh 10 male
let [,,gd] = ['oh',10,'male'];
console.log(gd); // male
let [n] = [];
console.log(n); // undefined
注意:
只要 = 两边的模式相同,那左边的变量与等号右边对应位置上的值进行相对应赋值操作。
如果 = 两边模式不相同,那么右边必须为可遍历对象才能进行赋值操作。
可遍历: Array、String、Map、Set、函数的arguments对象
不可遍历:true/false、NaN、undefined、null、{}
let [gender] = 'ohmylady';
console.log(gender); // o
let [gender] = true;
console.log(gender); // 报错,true不可迭代
数组默认值:
数组在解构时可以给定默认值,只有当数组对应位置上的值为【undefined】时,才会生效。默认值也可以引用解构赋值的其他变量,但前提是,该变量已经声明过了。
//代码一
let [name='oh'] = [];
console.log(name); // oh
//代码二
let [name='oh'] = ['张三'];
console.log(name); // 张三
//代码三
let [name='xpf'] = [null];
console.log(name); // null
//代码四
let [name,age,gender=name] = ['oh',10];
console.log(name,age,gender); // oh 10 oh
//代码五
let [name=name2,name2='oh'] = [];
console.log(name,name2); // 报错 name2未定义
2.2 对象解构
对象赋值
对象解构 和 数组解构的区别 :
数组解构 按照元素的顺序排列的,变量的取值根据所对应位置进行赋值。
对象解构 中的属性是没有次序的,变量和属性名同名进行赋值,否则无法正常取到值,与位置无关。
//代码一
let obj = {
name:'oh',
age:10,
gender:'male'
}
let {name,gender,age} = obj; //注意:是与位置无关的,根据名字来对应赋值
console.log(name,age,gender); //oh 10 male
//代码二
let {name,age,address} = obj;
console.log(name,age,address); //oh 10 undefined
对象解构的内部机制
//代码一
let {name,age,gender:address} = obj;
//等价于 let {name:name,age:age,gender:address} = obj
console.log(name,age,address); // oh 10 male
//代码二
let obj = {
name:'oh',
age:10,
gender:'male',
address:{
province:'湖南省',
city:'衡阳市'
}
}
//es5: var city = obj.address.city;
let {name,address:{city}} = obj;
console.log(name,city); // oh 衡阳市
对象默认值 :同数组默认值,只有当对象的属性值为undefined的时候,默认值才生效。
注:在ES6之前无法给函数参数赋默认值,在ES6中可以给函数赋默认值。
function Myajax(url,method='get',data){
console.log(url);
console.log(method);
}
Myajax('www.baidu.com')
3.对象扩展
简写:在ES6中可以对【对象函数】 和 【对象属性】进行简写
let name = 'oh';
let obj = {
name, //对象属性 简写形式 == name:name;
say(){} //对象函数 简写形式 == say:function(){}
}
构造函数中的方法:
- Object.is(value1,value2)
比较两个值是否相等,和===类似,也比较数据类型。
+0 和 -0使用该方法判断是,不相等;NaN判断是,等于自身。 - Object.assign(target,source1,source2,…)
使用1. 合并对象 :返回值为合并后的target目标对象
let obj = Object.assign({ },{ name:‘oh’ } , { age:10 } );
console.log(obj); // { name:‘oh’,age:10 }
使用2. 拷贝对象 :浅拷贝、深拷贝
在浅拷贝中,obj1中的address是会被obj2中的address完全替换掉的
//浅拷贝
let obj1 = {
name:'tom',
address:{
province:'安徽省',
city:'合肥市'
}
}
let obj2 = {
name:'sun',
address:{
province:'江苏省'
}
}
let obj = Object.assign(obj1,obj2);
console.log(obj);
如果需要实现深拷贝,可以使用JSON.stringify或者第三方库(lodash)
let obj3 = JSON.parse(JSON.stringify(obj1));
但是,如果对象中有方法,那么使用JSON.stringify就会丢失掉 该方法
let obj2 = obj1;
let obj3 = JSON.parse(JSON.stringify(obj1));
let obj4 = Object.assign({},obj1);
obj1.address.city = '苏州市';
console.log('obj1',obj1);
console.log('obj2',obj2);
console.log('obj3',obj3);
console.log('obj4',obj4);
//obj1 {name: 'tom',address: { privince: '江苏省', city: '苏州市',sayAddress: [Function: sayAddress] }}
//obj2 {name: 'tom',address: { privince: '江苏省', city: '苏州市',sayAddress: [Function: sayAddress] }}
//obj3 { name: 'tom', address: { privince: '江苏省', city: '合肥市' } }
//obj4 {name: 'tom',address: { privince: '江苏省', city: '苏州市',sayAddress: [Function: sayAddress] }}
- Object.setPrototypeOf(obj,prototype)
将一个对象的原型(prototype)设置到另一个对象obj中 - Object.getPrototypeOf(obj)
在ES5中,通过原型链继承可以继承到父类中的方法;在ES6中可以使用setProtorypeOf()方法可以继承父类中的方法和属性
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('hello');
}
var p1 = new Person();
p1.sayName();
function Dog(){
}
//es5:在创建子类实例之前
//子构造函数原型 指向 父构造函数实例
//子构造函数原型构造方法 指向 子类
//Dog.prototype = new Person();
//Dog.prototype.constructor = Dog;
var dog = new Dog();
//es6
Object.setPrototypeOf(dog,Person.prototype);
dog.sayName();
var res = Object.getPrototypeOf(dog1);
console.log(res); // Person { sayName: [Function] }
- Object.keys(obj)
- Object.values(obj)
- Object.entries(obj)
4.数组扩展
- Array.from(value) :将两类对象转换为真正的数组:类数组对象、可遍历对象(Set、Map)
- Array.of()
在使用Array构造函数创建一个数值的数组时,无法进行实现。Array.of()是为了弥补Array构造函数的这个不足。
let arr = new Array(3) // [ , , ] 创建的是长度为3的数组对象
let arr = Array.of(3); // [3] 创建的是有这个数值的数组对象 - find()与findIndex()
find() : 找出第一个满足条件的元素并返回,如果没有满足条件的元素时,返回undefined
findIndex() :数组中有一个indexOf()方法,也是查找第一个满足条件的元素索引,但是对于NaN的查找是查找不到的。为了弥补indexOf()的不足,可以使用findIndex()返回第一个满足条件的元素的索引,如果没有满足条件的元素时,返回-1 - fill(value1[,value2,value3]) : 使用给定值,填充数组
该方法可以有多参。value1 : 填充的数, value2 : 起始位置 , value3 : 结束位置(不包含) - keys、values、entries
这三个方法都用于数组的遍历,返回的都是一个遍历器对象(迭代器对象),该遍历器对象可用于for-of循环。
let arr = ['xpf','tom','larry];
//遍历方法一
let value_iterator = arr.values();
let item;
while(!(item = value_iterator.next()).done){
console.log(item.value); // xx tom larry
}
//遍历方法二
let values = arr.values();
for(let item of values){
console.log(item); // xx tom larry
}
//遍历方法三
for(let key in arr){
console.log(arr[key]); // xx tom larry
}
在遍历器对象中,提供一个next()方法,该方法会返回一个对象,表示当前数组的元素。value属性返回当前位置的元素, done属性是一个布尔值,表示遍历是否结束(即是否有必要再调用next方法)
let arr = ['xx','tom','larry'];
let iterator = arr.values();
console.log(iterator.next()); // { value: 'xx', done: false }
console.log(iterator.next()); // { value: 'tom', done: false }
console.log(iterator.next()); // { value: 'larry', done: false }
console.log(iterator.next()); // { value: undefined, done: true }
- includes() : includes是为了弥补indexOf方法的不足,includes()可以判断NaN是否在数组中存在,包含返回true,否则返回false
5.rest参数 : …变量名
- 在函数中使用时,就是将传递过来多余的参数进行存放在数组中。在ES6之前,函数的所有参数都会存在arguments对象中,在ES6中可以不需要arguments对象了。
function say(...params){
console.log(params); //['oh',10,'male']
}
say('oh',10,'male');
- 在对象中使用时,是对对象中的内容进行剥离出来。可以对两个对象进行合并操作
let obj1 = {name:'oh'};
let obj2 = {age:10,gender:'male'};
console.log({...obj1,...obj2});
//{name:'oh',age:10,gender:'male'}