由于 Babel 的强大和普及,现在 ES6/ES7 基本上已经是现代化开发的必备了。通过新的语法糖,能让代码整体更为简洁和易读。
声明 - let / const
: 块级作用域、不存在变量提升、暂时性死区、不允许重复声明 - const
: 声明常量,无法修改
解构赋值
class / extend
: 类声明与继承
异步解决方案:
Promise
的使用与实现
generator
:
yield
: 暂停代码next()
: 继续执行代码function* helloWorld() {yield "hello";yield "world";return "ending";}const generator = helloWorld();generator.next(); // { value: 'hello', done: false }generator.next(); // { value: 'world', done: false }generator.next(); // { value: 'ending', done: true }generator.next(); // { value: undefined, done: true }
await / async
: 是generator
的语法糖, babel 中是基于promise
实现。async function getUserByAsync() {let user = await fetchUser();return user;}const user = await getUserByAsync();console.log(user);
Set 和 Map 主要的应用场景在于 数据重组 和 数据储存 Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
英文版规范: Promises/A+规范
中文版规范: Promises/A+规范(中文)
Promise 标准仅描述了 then 方法的行为,未对 catch、all、race 方法进行描述,也未规范如何创建一个 Promise 对象。ES6 中 Promise 提供了以下 API。
function Promise(resolver) {}
Promise.prototype.then = function() {};Promise.prototype.catch = function() {};
Promise.resolve = function() {};Promise.reject = function() {};Promise.all = function() {};Promise.race = function() {};
const promise = new Promise((resolve) => {setTimeout(() => {resolve(1);}, 2000);});promise.then((a) => alert(a));promise.then((a) => alert(a + 1));
构造函数用法总结:
function Promise(executor) {var self = this;self.status = "pending"; //promise当前的状态self.data = undefined; //promise的值self.onResolvedCallback = [];//promise状态变为resolve时的回调函数集,可能有多个function resolve(value) {if (self.status === "pending") {self.status = "resolved";self.data = value;for (var i = 0; i < self.onResolvedCallback.length; i++) {self.onResolvedCallback[i](value);}}}executor(resolve);}Promise.prototype.then = function(resolve) {this.onResolvedCallback.push(resolve);};
function Promise(executor) {var self = this;self.status = "pending"; //promise当前的状态self.data = undefined; //promise的值self.onResolvedCallback = [];//promise状态变为resolve时的回调函数集,可能有多个self.onRejectedCallback = [];//promise状态变为reject时的回调函数集,可能有多个function resolve(value) {if (self.status === "pending") {self.status = "resolved";self.data = value;for (var i = 0; i < self.onResolvedCallback.length; i++) {self.onResolvedCallback[i](value);}}}function reject(reason) {if (self.status === "pending") {self.status = "rejected";self.data = reason;for (var i = 0; i < self.onRejectedCallback.length; i++) {self.onRejectedCallback[i](reason);}}}try {executor(resolve, reject);} catch (e) {reject(e);}}Promise.prototype.then = function(onResolve, onReject) {this.onResolvedCallback.push(onResolve);this.onRejectedCallback.push(onReject);};
总结: ①executor 函数作为实参在创建 Promise 对象时传入 Promise 构造函数。 ②resolve 和 reject 函数作为实参传入 executor 函数。 ③value 作为实参传入 resolve 和 reject 函数。
const promise = new Promise((resolve) => {resolve(1);});promise.then((a) => alert(a));
解决办法:需要将 promise 的 resolve 和 reject 异步执行。
function resolve(value) {setTimeout(function() {if (self.status === "pending") {self.status = "resolved";self.data = value;for (var i = 0; i < self.onResolvedCallback.length; i++) {self.onResolvedCallback[i](value);}}});}function reject(reason) {setTimeout(function() {if (self.status === "pending") {self.status = "rejected";self.data = reason;for (var i = 0; i < self.onRejectedCallback.length; i++) {self.onRejectedCallback[i](reason);}}});}
Promise.prototype.then = function(onResolved, onRejected) {var self = this;var promise2;onResolved =typeof onResolved === "function"? onResolved: function(value) {return value;};onRejected =typeof onRejected === "function"? onRejected: function(reason) {throw reason;};//promise对象当前状态为resolvedif (self.status === "resolved") {return (promise2 = new Promise(function(resolve, reject) {try {//调用onResolve回调函数var x = onResolved(self.data);//如果onResolve回调函数返回值为一个promise对象if (x instanceof Promise) {//将它的结果作为promise2的结果x.then(resolve, reject);} else {resolve(x); //执行promise2的onResolve回调}} catch (e) {reject(e); //执行promise2的onReject回调}}));}//promise对象当前状态为rejectedif (self.status === "rejected") {return (promise2 = new Promise(function(resolve, reject) {try {var x = onRejected(self.data);if (x instanceof Promise) {x.then(resolve, reject);} else {resolve(x);}} catch (e) {reject(e);}}));}//promise对象当前状态为pending//此时并不能确定调用onResolved还是onRejected,需要等当前Promise状态确定。//所以需要将callBack放入promise1的回调数组中if (self.status === "pending") {return (promise2 = new Promise(function(resolve, reject) {self.onResolvedCallback.push(function(value) {try {var x = onResolved(self.data);if (x instanceof Promise) {x.then(resolve, reject);} else {resolve(x);}} catch (e) {reject(e);}});self.onRejectedCallback.push(function(reason) {try {var x = onRejected(self.data);if (x instanceof Promise) {x.then(resolve, reject);} else {resolve(x);}} catch (e) {reject(e);}});}));}};
function resolvePromise(promise2, x, resolve, reject) {var then;var thenCalledOrThrow = false;if (promise2 === x) {return reject(new TypeError("Chaining cycle detected for promise!"));}if (x instanceof Promise) {if (x.status === "pending") {//because x could resolved by a Promise Objectx.then(function(v) {resolvePromise(promise2, v, resolve, reject);}, reject);} else {//but if it is resolved, it will never resolved by a Promise Object but a static value;x.then(resolve, reject);}return;}if (x !== null && (typeof x === "object" || typeof x === "function")) {try {then = x.then; //because x.then could be a getterif (typeof then === "function") {then.call(x,function rs(y) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return resolvePromise(promise2, y, resolve, reject);},function rj(r) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return reject(r);});} else {resolve(x);}} catch (e) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return reject(e);}} else {resolve(x);}}Promise.prototype.then = function(onResolved, onRejected) {var self = this;var promise2;onResolved =typeof onResolved === "function"? onResolved: function(v) {return v;};onRejected =typeof onRejected === "function"? onRejected: function(r) {throw r;};if (self.status === "resolved") {return (promise2 = new Promise(function(resolve, reject) {setTimeout(function() {// 异步执行onResolvedtry {var x = onResolved(self.data);resolvePromise(promise2, x, resolve, reject);} catch (reason) {reject(reason);}});}));}if (self.status === "rejected") {return (promise2 = new Promise(function(resolve, reject) {setTimeout(function() {// 异步执行onRejectedtry {var x = onRejected(self.data);resolvePromise(promise2, x, resolve, reject);} catch (reason) {reject(reason);}});}));}if (self.status === "pending") {// 这里之所以没有异步执行,是因为这些函数必然会被resolve或reject调用,而resolve或reject函数里的内容已是异步执行,构造函数里的定义return (promise2 = new Promise(function(resolve, reject) {self.onResolvedCallback.push(function(value) {try {var x = onResolved(value);resolvePromise(promise2, x, resolve, reject);} catch (r) {reject(r);}});self.onRejectedCallback.push(function(reason) {try {var x = onRejected(reason);resolvePromise(promise2, x, resolve, reject);} catch (r) {reject(r);}});}));}};
var Promise = (function() {function Promise(resolver) {if (typeof resolver !== "function") {//resolver必须是函数throw new TypeError("Promise resolver " + resolver + " is not a function");}if (!(this instanceof Promise)) return new Promise(resolver);var self = this; //保存thisself.callbacks = []; //保存onResolve和onReject函数集合self.status = "pending"; //当前状态function resolve(value) {setTimeout(function() {//异步调用if (self.status !== "pending") {return;}self.status = "resolved"; //修改状态self.data = value;for (var i = 0; i < self.callbacks.length; i++) {self.callbacks[i].onResolved(value);}});}function reject(reason) {setTimeout(function() {//异步调用if (self.status !== "pending") {return;}self.status = "rejected"; //修改状态self.data = reason;for (var i = 0; i < self.callbacks.length; i++) {self.callbacks[i].onRejected(reason);}});}try {resolver(resolve, reject); //执行resolver函数} catch (e) {reject(e);}}function resolvePromise(promise, x, resolve, reject) {var then;var thenCalledOrThrow = false;if (promise === x) {return reject(new TypeError("Chaining cycle detected for promise!"));}if (x !== null && (typeof x === "object" || typeof x === "function")) {try {then = x.then;if (typeof then === "function") {then.call(x,function rs(y) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return resolvePromise(promise, y, resolve, reject);},function rj(r) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return reject(r);});} else {return resolve(x);}} catch (e) {if (thenCalledOrThrow) return;thenCalledOrThrow = true;return reject(e);}} else {return resolve(x);}}Promise.prototype.then = function(onResolved, onRejected) {//健壮性处理,处理点击穿透onResolved =typeof onResolved === "function"? onResolved: function(v) {return v;};onRejected =typeof onRejected === "function"? onRejected: function(r) {throw r;};var self = this;var promise2;//promise状态为resolvedif (self.status === "resolved") {return (promise2 = new Promise(function(resolve, reject) {setTimeout(function() {try {//调用then方法的onResolved回调var x = onResolved(self.data);//根据x的值修改promise2的状态resolvePromise(promise2, x, resolve, reject);} catch (e) {//promise2状态变为rejectedreturn reject(e);}});}));}//promise状态为rejectedif (self.status === "rejected") {return (promise2 = new Promise(function(resolve, reject) {setTimeout(function() {try {//调用then方法的onReject回调var x = onRejected(self.data);//根据x的值修改promise2的状态resolvePromise(promise2, x, resolve, reject);} catch (e) {//promise2状态变为rejectedreturn reject(e);}});}));}//promise状态为pending//需要等待promise的状态改变if (self.status === "pending") {return (promise2 = new Promise(function(resolve, reject) {self.callbacks.push({onResolved: function(value) {try {//调用then方法的onResolved回调var x = onResolved(value);//根据x的值修改promise2的状态resolvePromise(promise2, x, resolve, reject);} catch (e) {//promise2状态变为rejectedreturn reject(e);}},onRejected: function(reason) {try {//调用then方法的onResolved回调var x = onRejected(reason);//根据x的值修改promise2的状态resolvePromise(promise2, x, resolve, reject);} catch (e) {//promise2状态变为rejectedreturn reject(e);}},});}));}};//获取当前Promise传递的值Promise.prototype.valueOf = function() {return this.data;};//由then方法实现catch方法Promise.prototype.catch = function(onRejected) {return this.then(null, onRejected);};//finally方法Promise.prototype.finally = function(fn) {return this.then(function(v) {setTimeout(fn);return v;},function(r) {setTimeout(fn);throw r;});};Promise.prototype.spread = function(fn, onRejected) {return this.then(function(values) {return fn.apply(null, values);}, onRejected);};Promise.prototype.inject = function(fn, onRejected) {return this.then(function(v) {return fn.apply(null,fn.toString().match(/\((.*?)\)/)[1].split(",").map(function(key) {return v[key];}));}, onRejected);};Promise.prototype.delay = function(duration) {return this.then(function(value) {return new Promise(function(resolve, reject) {setTimeout(function() {resolve(value);}, duration);});},function(reason) {return new Promise(function(resolve, reject) {setTimeout(function() {reject(reason);}, duration);});});};Promise.all = function(promises) {return new Promise(function(resolve, reject) {var resolvedCounter = 0;var promiseNum = promises.length;var resolvedValues = new Array(promiseNum);for (var i = 0; i < promiseNum; i++) {(function(i) {Promise.resolve(promises[i]).then(function(value) {resolvedCounter++;resolvedValues[i] = value;if (resolvedCounter == promiseNum) {return resolve(resolvedValues);}},function(reason) {return reject(reason);});})(i);}});};Promise.race = function(promises) {return new Promise(function(resolve, reject) {for (var i = 0; i < promises.length; i++) {Promise.resolve(promises[i]).then(function(value) {return resolve(value);},function(reason) {return reject(reason);});}});};Promise.resolve = function(value) {var promise = new Promise(function(resolve, reject) {resolvePromise(promise, value, resolve, reject);});return promise;};Promise.reject = function(reason) {return new Promise(function(resolve, reject) {reject(reason);});};Promise.fcall = function(fn) {// 虽然fn可以接收到上一层then里传来的参数,但是其实是undefined,所以跟没有是一样的,因为resolve没参数啊return Promise.resolve().then(fn);};Promise.done = Promise.stop = function() {return new Promise(function() {});};Promise.deferred = Promise.defer = function() {var dfd = {};dfd.promise = new Promise(function(resolve, reject) {dfd.resolve = resolve;dfd.reject = reject;});return dfd;};try {// CommonJS compliancemodule.exports = Promise;} catch (e) {}return Promise;})();