let、const
和 var 不一样的是,let 和 const 不存在变量提升
var存在的问题:
- var有作用域问题(会污染全局作用域)
- var可已重复声明
- var会变量提升预解释
- var不能定义常量
而let const
- let、const不可以重复声明
- let、const不会声明到全局作用域上
- let、const不会预解释变量
- const做常量声明(一般常量名用大写)
//1. 作用域
//var
var a = 5;
console.log(window.a); //5
//let、const
let a = 5;
console.log(window.a); //undefined
//有一个问题,let定义的a声明到哪里了呢?欢迎解释(:
//2. 重复声明
//var
var a = 5;
var a = 6;
//let、const
let a = 5;
let a = 6; //Identifier 'a' has already been declared 不能重复声明
//3. 预解释
//var
console.log(a); //undefined 相当于 var a;
var a = 5;
//let const
console.log(a)//Uncaught ReferenceError: a is not defined 语法错误,没有预解释
let a = 5;
//4. 常量
//var
var a = 5;
a = 6;
//const
const a = 5;
a = 6;//Uncaught TypeError: Assignment to constant variable. 语法错误
模板字符串
模板字符串是为了解决使用+号拼接字符串的不便利而出现的。它的功能非常强大,但是我们大多数时候使用它则非常简单。看一个例子大家就明白怎么使用了。
// es6
const a = 20;
const b = 30;
const string = `${a}+${b}=${a+b}`;
// es5
var a = 20;
var b = 30;
var string = a + "+" + b + "=" + (a + b);
箭头函数
- 写法上的不同,箭头函数更加简洁
// es5
var fn = function(a, b) {
return a + b;
}
// es6 箭头函数写法,当函数直接被return时,可以省略函数体的括号
const fn = (a, b) => a + b;
// es5
var foo = function() {
var a = 20;
var b = 30;
return a + b;
}
// es6
const foo = () => {
const a = 20;
const b = 30;
return a + b;
}
- 不改变this指向
function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
return arr.map(character => this.name + character);
};
展开运算符
在ES6中用...来表示展开运算符,它可以将数组方法或者对象进行展开。
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 10, 20, 30];
// 这样,arr2 就变成了[1, 2, 3, 10, 20, 30];
展开对象数据也是可以得到类似的结果
const obj1 = {
a: 1,
b: 2,
c: 3
}
const obj2 = {
...obj1,
d: 4,
e: 5,
f: 6
}
// 结果类似于 const obj2 = Object.assign({}, obj1, {d: 4})
includes
//判断字符串中是否包含某个字符串
let str = 'woaini';
str.includes('ai'); //true
解析结构(解构)
解析结构是一种全新的写法,可以让我们用一个更简便的语法从一个数组或者对象(即使是深层的)中分离出来值,并存储他们。
// es6
const arr = [1, 2, 3];
const [a, b, c] = arr;
// es5
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
函数默认参数
ES6 中,函数的参数可以支持设置默认值:
function addTwoNumbers(x=0, y=0) {
return x + y;
}
addTwoNumbers(2, 4);
addTwoNumbers(2);
addTwoNumbers();
类 Classes
ES6为我们创建对象提供了新的语法糖,这就是Class语法。如果你对ES5中面向对象的方式比较熟悉的话,Class掌握起来也是非常迅速的,因为除了写法的不同,它并不会增加新的难以理解的知识点。我们先利用一个简单的例子来看看写法的不同。
// ES5
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 原型方法
Person.prototype.getName = function() {
return this.name
}
// ES6
class Person {
constructor(name, age) { // 构造函数
this.name = name;
this.age = age;
}
getName() { // 原型方法
return this.name
}
}
class Parent{
constructor(name){
this.name = name;
}
getName(){
return this.name;
}
static fn(){
return 9;
}
}
class Child extends Parent{
constructor(name,age){
super(name);//子类有构造函数必须有super
this.age = age;
}
}
let child = new Child('xingxing',9);
console.log(child.getName());//xingxing
console.log(child.name);//xingxing
console.log( Child.fn() );//9
继承 extends
相比ES5,ES6的继承就要简单很多,我们直接来看一个例子。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
getName() {
return this.name
}
}
// Student类继承Person类
class Student extends Person {
constructor(name, age, gender, classes) {
super(name, age);
this.gender = gender;
this.classes = classes;
}
getGender() {
return this.gender;
}
}
我们只需要一个extends关键字,就可以实现继承了,不用像ES5那样去担心构造函数继承和原型继承,除此之外,我们还需要关注一个叫做super的方法。
在继承的构造函数中,我们必须如上面的例子那么调用一次super方法,它表示构造函数的继承,与ES5中利用call/apply继承构造函数是一样的功能。
// 构造函数中
// es6
super(name, age);
// es5
Person.call(this);
async await
- async用来修饰函数,需要配合await
- await后只能跟promise
let bluebird = require('bluebird');
let fs = require('fs');
let read = bluebird.promisify(fs.readFile);
//await 后只能跟promise
async function r(){
let content1 = await read('./1.txt','utf8');
let content2 = await read(content1,'utf8');
return content2;
}
//async返回promise
r().then(function(data){
console.log(data);
})
async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变
也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。
const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
await delay(1000);
await delay(2000);
await delay(3000);
return 'done';
}
f().then(v => console.log(v)); // 等待6s后才输出 'done'
看这里
Promise
看这里