你应该知道的ES6
ES和js的关系:
Javascript 包含三部分:ECMAScript(核心), Dom(文档对象模型), Bom(浏览器对象模型)。
ES作为核心,它规定了语言的组成部分:语法、类型、语句、关键字、保留字、操作符、对象;
DOM把整个页面映射为一个多层节点的结果,开发人员可借助DOM提供的API,轻松地删除、添加、替换或修改任何节点。
BOM支持可以访问和操作浏览器窗口的浏览器对象模型,开发人员可以控制浏览器显示的页面以外的部分。
let & const:
使用let
声明的变量可以重新赋值,但是不能在同一作用域内重新声明
使用const
声明的变量必须赋值初始化,但是不能在同一作用域内重新声明也无法重新赋值(可以修改声明对象的内部属性).
let const 也存在变量提升,只不过由于暂时死区的限制,你不能在 let/const x 之前使用 x;
x = 'hl'; (() => { console.log(x); //x is not defined let x = 'zpy'; })()
字符串模板:
ES6中允许使用反引号 `` 来创建字符串,``可以包含由美元符号加花括号包裹的变量 `${变量}`
let a = 'boy'; let b = `this is a ${a}, good &{a}`; console.log(b) // this is a boy, good boy
多行字符串:
var hl = ` 你应该知道的ES6 你应该知道的ES6 你应该知道的ES6 `
解构赋值:
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring).
// 之前的赋值 var a = 1, b =2, c = 3;
// 简单的结构赋值 var [a, b, c] = [1, 2, 3];
数组结构赋值
// 多维数组的结构赋值 var [a, [b], [[c]]]] = ['h',['l'], [['z']]]; console.log(a,b,c) // 'h' 'l' 'z' //默认值,只有当右边对应位置为undefined时候才会选择默认(null不属于undefined) var [a = 1, b = 2, c] = ['undefined', null, '3']; console.log(a,b,c) // '1' 'null' '3' var [a, b, c] = [1, 2]; console.log(a,b,c) // 1 2 undefined var [a, b] = [1, 2, 3]; console.log(a,b) // 1 2
对象结构赋值
var {name, age} = { name: "hl", age:26 }; console.log(name, age) // 'hl' 26 var {id: personId, name = 'zpy', age} = { name: "hl", age:26, id:007 }; console.log(personId, name, age) //7 'hl' 26
字符串结构赋值
var [a, b, c] = 'this'; console.log(a, b, c);// 't' 'h' 'i' var {length: len} = 'this'; console.log(len) // 4
箭头函数
ES6允许使用“箭头”(=>
)定义函数。
var f = () => 5; // 默认return
// 等同于
var f = function () {
return 5;
};
var sum = (num1, num2) => num1 + num2; // 默认return
// 等同于
//如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return
语句返回。
var sum = function(num1, num2) {
return num1 + num2;
};
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
var getTempItem = id => ({ id: id, name: "Temp" });
箭头函数有几个使用注意点。
(1)函数体内的this
对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new
命令,否则会抛出一个错误。
(3)不可以使用arguments
对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
(4)不可以使用yield
命令,因此箭头函数不能用作Generator函数。
箭头函数的this指向:
var obj={ num:1, fn:function(){ setTimeout(function(){ console.log(this.num); // this => window }); } } obj.fn();//undefined //------------------------------------------- var obj1={ num: 2, fn: function() { setTimeout(() => { console.log(this.num); // this => obj1 }); } }; obj1.fn();// 2
箭头函数转换成ES5
// ES6 function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } // ES5 function foo() { var _this = this; setTimeout(function () { console.log('id:', _this.id); }, 100); }
默认参数
//传统的指定默认参数的方式 function sayHello(name) { var name = name || 'hl'; console.log('Hello '+name); } //运用ES6的默认参数 const sayHello2 = (name = 'hl') => { console.log(`Hello ${name}`); }; sayHello(); // Hello hl sayHello('zpy'); // Hello zpy sayHello2(); // Hello hl sayHello2('zpy'); // Hello zpy
延展操作符
let a = [1, 2, 3]; const fn = (a) => console.log(...a); fn(a); // 1 2 3
let obj = { a: 1, b: 2 };
let obj2 = {...obj, c: 3};
console.log(obj2); // {a: 1, b: 2, c: 3}
Class
JavaScript语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子。
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.sayHello = function () { return 'Hello' + this.x + ',' + this.y; }; var p = new Point('hl', 'zpy');
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class
关键字,可以定义类。基本上,ES6的class
可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用ES6的“类”改写,就是下面这样。
//定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } sayHello() { return `Hello ${this.x}, ${this.y}` } }
类的继承
子类必须在constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类没有自己的this
对象,而是继承父类的this
对象,然后对其进行加工。如果不调用super
方法,子类就得不到this
对象
class Father { constructor(name, age) { this.name = name; this.age = age; } love() { console.log(this.name); } } class Son extends Father { constructor(name, id, age) { super(name, age); this.id = id; } fn() { console.log(this.id); console.log(this.name); console.log(this.age); } }
Module
ES6的Class只是面向对象编程的语法糖,升级了ES5的构造函数的原型链继承的写法,并没有解决模块化问题。Module功能就是为了解决这个问题而提出的。
在ES6以前JavaScript并不支持本地的模块。人们想出了AMD,RequireJS,CommonJS以及其它解决方法。现在ES6中可以用模块import 和export 操作了。
// es5 var service = require('module.js'); // es6 import {add, getId} from 'module'; //用service表示module.js文件 import * service form 'module';
Promise
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise
对象。
Promise
对象有以下两个特点。
(1)对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:Pending
(进行中)、Resolved
(已完成,又称Fulfilled)和Rejected
(已失败)。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise
对象的状态改变,只有两种可能:从Pending
变为Resolved
和从Pending
变为Rejected
。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
有了Promise
对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise
对象提供统一的接口,使得控制异步操作更加容易。
Promise
也有一些缺点。首先,无法取消Promise
,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。第三,当处于Pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
var promise = new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } }); promise.then(function(value) { // success }, function(error) { // failure });