ES6
1.let和const关键字
使用let关键字代替var关键字
使用const关键字声明常量
let特点
- 不允许重复声明同名变量
- 在块作用域内有效
- 不会预处理,不存在变量提升
预处理:提前声明变量和定义函数
const特点
- 声明的变量不允许修改
2.变量的解构赋值
从对象或数组中提取数据,并赋值给多个变量。变量名必须和对象内的一致
//解构对象
let obj = { username: 'kobe', age: 39};
let {username , age} = obj; //username=kobe age=39
//解构对象
let arr = [1, 3, 5, 'abc', true];
let [,,a, b] =arr;//通过下标给变量赋值
console.log(a, b);
//传参解构
function foo({username, age}){
console.log(username, age);
}
foo(obj);
3.模板字符串
简化字符串的拼接,例如使用在拼接url字符串时
let obj = { username: 'kobe', age: 39};
let str = `姓名:${obj.username},年龄:${obj.age}`; //使用tab键上面的键
4.对象的简写方式
提供了一种创建对象的快捷方式
let username = 'kobe';
let age =30;
let obj = {
username,//同名属性可以省略不写,等价于 username: username
age,
getUsername(){ //可以省略function
return this.username;
}
}
5.箭头函数
使用箭头函数简化部分函数的创建
//只有一条函数执行语句的情况,可以省略花括号
let fun = () => console.log('Hello World'); //没有形参
let fun = a => console.log('Hello World', a); //只有一个参数,可以省略括号
let fun = (a, b) => console.log('Hello World', a, b); //两个及以上参数
//含有多条执行语句,加上花括号
let fun = () => {
console.log('Hello World');
console.log('Hello World');
return 'hi';
}
箭头函数没有自己的this,其this决定定义的时候处在的对象,而不是调用的时候
6.三点运算符
可以用来当作可变参数,类似java,只能放在函数的最后
// 函数参数的用法
function foo(a,b,...value){ //value以伪数组的方式传入
value.forEach(function(item, index){
console.log(item, index);
});
}
// 数组中的用法
let arr = [1,6];
let arr1 = [2, 3, 4, 5];
arr = [1, ...arr1, 6]; //将arr1插入
7.形参默认值
可以在参数上指定参数的默认值,同其他语言
8.Promise对象
代表了未来某个将要发生的时间,通常是一个异步操作
有了promise对象可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数
创建并使用Promise对象
let promise = new Promise(((resolve, reject) => {
console.log('Hello');
setTimeout(() => { //此处可以执行定时任务或者ajax异步任务
console.log('Hi');
//如果执行成功则修改promise的状态为fullfilled
// resolve(data);
//如果执行失败则修改状态为reject
// reject(data);
}, 2000);
}));
//使用promise设置回调函数
promise.then((data) => { //第一个表示成功的回调
console.log('成功回调');
}, (data) => { //第二个表示失败的回调
console.log('失败回调');
});
Promise对象的三个状态
- pending:初始化状态
- fullfilled:成功状态
- rejected:失败状态
9.Symbol属性
ES5中对象的属性名都是字符串,容易造成重名,污染环境
特点
- Symbol属性对应的值是唯一的,解决命名冲突问题
- Symbol值不能与其他数据进行计算,包括同字符串拼串
- for in , for of 遍历时都不会遍历Symbol属性
//创建一个Symbol属性
let symbol = Symbol();
console.log(symbol);
let obj = {username: 'kobe', age: 39};
obj[symbol] = 'hello'; //使用中括号的方式设置Symbol属性
console.log(obj);
10.Iterator迭代器
Iterator是一种接口机制,为不同的数据解构提供统一的访问机制,可以使用for of 语句
支持迭代器的数据类型
- 数组
- 字符串
- arguments
- set容器
- map容器
使用方法
let arr = [1, 2, 3, 4];
for(let i of arr){ //输出数组
console.log(i);
}
11.Generator函数
ES6提供的解决异步编程的方案之一,Generator函数是一个状态机,内部封装了不同状态的数据,用来生成遍历器对象
特性
- 可以暂停函数(惰性求值),yield可以暂停,next方法可以启动,每次换回的是yield后的表达式结果
- function与函数名之间有一个星号,即 function*
- generator函数返回的是指针对象,不会执行函数内部的逻辑
- 调用next方法从上次暂停处向下执行,直到遇到下一个yield表达式
//Generator函数
function* myGenerator() {
console.log("开始执行");
yield 'hello';
console.log("继续执行");
yield 'world';
yield console.log('再次执行');
}
let mg = myGenerator(); //返回的是指针对象
let iteratorResult = mg.next();
console.log(iteratorResult.value); //通过结果获取返回值,yield语句默认返回是undefined
mg.next();//继续执行
mg.next();//再次执行
使用Generator函数为对象生成迭代器
//对象的Symbol.iterator属性,指向遍历器对象
let obj = {username : 'kobe', age: 42};
obj[Symbol.iterator] = function* () { //设置iterator
yield 1;
yield 2;
yield 3;
};
for (let i of obj) {
console.log(i);//输出1 2 3
}
12.async函数
async函数是ES7中规定的内容,类似于Generator函数,是基于它的再一次封装
特点
- 不需要像Generator一样去调用next方法,遇到await等待,当前的异步操作完成之后就自动向下执行
- 返回的总是Promise对象,可以用then方法进行下一步操作
- async取代Generator的* ,await取代yield
基本使用
//基本使用
async function foo() {
return new Promise(resolve => {
setTimeout(function () {
console.log('foo执行');
resolve();
}, 2000);
});
}
async function test() {
console.log('开始执行');
await foo(); //等待foo执行完毕后进行下一条语句
console.log('执行完毕');
}
test(); //调用函数测试
示例使用
//示例使用
async function getRequest(url) {
return new Promise((resolve, reject) => {
$.ajax({
method: 'GET',
url: url,
success: data => resolve(),
error: data => reject
})
});
}
async function test2() {
await getRequest('http://localhost:L8080');
}
13.class类
使用class可以创建类和实现类的继承
基本使用
使用class关键字定义类时,类的方法不可以加function关键字
使用constructor关键字来定义一个构造器
//创建一个Person类
class Person {
//构造器
constructor(name, age) {
this.name = name;
this.age = age;
}
//类的一般方法
showName() {
console.log(this.name, this.age)
}
}
let person = new Person('kobe', 39);
person.showName();
类的继承
此处类的继承类似于java中的机制
//定义一个子类StarPerson
class StarPerson extends Person {
constructor(name, age) { //构造父类的构造器,同Java
super(name, age);
}
}
14.数组方法扩展
- Array.from(v):将伪数组或可遍历对象转换成真数组
- Array.of(v1, v2, v2):将一系列值转换成数组
- find(function(value, index, arr){return true}):找出第一个满足条件返回true的元素
- find(function(value, index, arr){return true}):找出第一个满足条件返回true的元素下标
15.对象方法扩展
- Object.is(v1, v2):判断两个数据是否完全相等
- Object.assign(target, source1, source2…):将源对象属性复制到目标对象上
- 直接操作__proto__属性:obj2.__proto__ = obj1;
区别于普通的比较
console.log(0 == -0); //true
console.log(NaN == NaN); //false
console.log(Object.is(0, -0)); //false
console.log(Object.is(NaN, NaN)); //true
16.深拷贝和浅拷贝
深拷贝和浅拷贝的区别:当一个变量x被赋值另一个变量y时,x的变化会影响到y的变化,这就是浅拷贝(只拷贝了引用)。而x的变化对于y没有影响的话,这就是深拷贝(复制了堆内存)
浅拷贝
- 基本数据类型
- Object.assign()
- Array.prototype.concat()
- Array.prototype.slice()
深拷贝
- JSON.parse(JSON.stringify())
- 对象
- 数组
- 拷贝数据里不能有函数