收录 项目开发当中经常使用ES六、七、8的 知识点javascript
ES6推荐的编码风格:es6.ruanyifeng.com/#docs/style值得注意java
ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现es6
2015年6月正式经过成为国际标准。ajax
Babel 是一个普遍使用的 ES6 转码器,能够将 ES6 代码转为 ES5 代码,从而在现有环境执行。编程
var的时代主要有三大痛点:json
ES6 const和let的出现就是为了解决以上三个痛点。数组
声明后不可再次修改,不然会报错。promise
支持块级做用域浏览器
// var 的状况
console.log(foo); // 输出undefined
var foo = 2;
// let 的状况
console.log(bar); // 报错ReferenceError
let bar = 2;
复制代码
同一块级做用域{}下不可重复声明bash
块级做用域的出现,使得得到普遍应用的匿名当即执行函数表达式(匿名 IIFE)再也不必要了。
反例:
window.onload=function (){
var aBtn = document.getElementsByTagName('input');
for(var i=0;i < aBtn.length;i++){
aBtn[i].onclick=function (){
alert(i); //猜测弹出的i是多少?
};
}
};
复制代码
对象的解构与数组有一个重要的不一样。 数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
// 左边和右边 必须对应起来
对象:
let {a, b, c } = {a:123, b:12313, c:35234234} // 对象解构赋值
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
数组:
let [a, b, c] = [12, 5, 8]; // 数组解构赋值
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [bar, foo] = [1];
以上状况都属于解构不成功,foo的值都会等于undefined。
复制代码
let url='http://www.bing.com/a';
url.startsWith('http://') || url.startsWith('https://')
url.startsWith('http') // true
url.endsWith('a') // true
url.includes('o') // true
复制代码
Math.trunc
方法用于去除一个数的小数部分,返回整数部分。
Math.trunc(4.1) // 4
Math.trunc(-4.1) // -4
Math.trunc(-0.1234) // -0
复制代码
形式为...变量名
),用于获取函数的多余参数,这样就不须要使用arguments
对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function push(array, ...items) {
复制代码
主要修复this指向的问题。 函数体内的this对象 就是定义时所在的对象,而不是以前使用时所在的对象。
function(参数){ }
(参数)=>{ return xxx }
若是,有且仅有1个参数,()也能够省
若是,有且仅有1条语句-return,{}能够省
复制代码
aItems.filter(item=>item.loc==cur_loc) //单个条件
.filter(item=>item.price>=60 && item.price<100);//多个条件
求和、求平均数...
Array.from
方法用于将两类对象转为真正的数组:相似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
复制代码
[1, 4, -5, 10].find((n) => n < 0)
// -5
复制代码
Array.prototype.includes
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes
方法相似
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
复制代码
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
复制代码
Object.assign
方法用于对象的合并,将源对象(source)的全部可枚举属性,复制到目标对象(target)。
let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);
复制代码
ES5 的Object.getOwnPropertyDescriptor()
方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()
方法,返回指定对象全部自身属性(非继承属性)的描述对象。
是异步编程的一种解决方案,比传统的 -- 回调函数和事件 更合理和更强大。
两大特色:
pending
(进行中)、fulfilled
(已成功)和rejected
(已失败),只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。有了Promise
对象,就能够将异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。此外,Promise
对象提供统一的接口,使得控制异步操做更加容易。
建立一个Promise实例
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操做成功 */){
resolve(value);
} else {
reject(error);
}
});
复制代码
Promise
实例生成之后,能够用then
方法分别指定resolved
状态和rejected
状态的回调函数。
promise.then(function(value) {
// success 状态变为resolved时调用
}, function(error) {
// failure 状态变为rejected时调用
});
复制代码
Promise.prototype.catch
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
复制代码
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
复制代码
p
的状态由p1
、p2
、p3
决定,分红两种状况。 (1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。 (2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
Promise.all([
$.ajax({url: 'data/1.json', dataType: 'json'}),
$.ajax({url: 'data/2.json', dataType: 'json'}),
$.ajax({url: 'data/3.json', dataType: 'json'}),
]).then((arr)=>{
let [data1, data2, data3]=arr;
console.log(data1, data2, data3);
}, (res)=>{
alert('错了');
});
复制代码
ES2017标准引入async函数,使得异步操做变得更加方便。它是 Generator函数的语法糖。
进一步说,async
函数彻底能够看做多个异步操做,包装成的一个 Promise 对象,而await
命令就是内部then
命令的语法糖。
生成实例对象的传统方法是经过 构造函数,
function Point (x, y) {
this.x = x;
this.y = y
}
Point.prototype.toString = function () {
return this.x + this.y
}
var p = new Point(1, 2)// 3
复制代码
ES6引入Class的概念,让 对象原型的写法更加清晰、更像面向对象编程的语法(就是一个语法糖)
class Point () {
constructor(x, y) { // 构造函数 一个类必须有constructor方法
this.x = x;
this.y = y;
}
toString() {
return this.x + this.y;
}
}
var p = new Point();
p.toString() //
复制代码
Class 能够经过extends
关键字实现继承,这比 ES5 的经过修改原型链实现继承,要清晰和方便不少。
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
复制代码
super: 既能够 看成函数使用,也能够看成对象使用。 子类必须在constructor
方法中调用super
方法,不然新建实例时会报错。 super
它在这里表示父类的构造函数,用来新建父类的this
对象。
在ES6以前 社区主要有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。 ES6的诞生彻底取代了二者,成为 浏览器和服务器通用的模块解决方案。
特色: es6模块的设计思想是 尽可能的静态化,使得编译时就能肯定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD 都只能在运行时肯定这些东西。
基础 ES6 模块不是对象,而是经过export
命令显式指定输出的代码,再经过import
命令输入。
// profile.js
export var firstName = 'Michael'; //1. 普通方式
var year = 1958; // 2. 使用{}指定索要输出的一组变量 (推荐写法)
export { year };
// export-default.js
export default function() {xxx} //3. 默认输出函数,其余模块加载该模块时,import命令能够为该匿名函数指定任意名字。
// import-default.js
import customName from './export-default';
customName(); // 'foo'
复制代码
默认方式:
<!-- 外部脚本 -->
<script type="application/javascript" src="path/to/myModule.js"></script>
//默认状况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到<script>标签就会停下来,等到执行完脚本,再继续向下渲染。
复制代码
ES6 方式:
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
// <script>标签打开defer或async属性,脚本就会异步加载。
复制代码
一句话,defer
是“渲染完再执行”,async
是“下载完就执行”。另外,若是有多个defer
脚本,会按照它们在页面出现的顺序加载,而多个async
脚本是不能保证加载顺序的。
**ES6模块: **浏览器加载 ES6 模块,也使用<script>
标签,可是要加入type="module"
属性。、
<script type="module" src="./foo.js"></script>
复制代码