ES6 核心总结

模块化(module):

export default / export 暴露,import 引入

注意:
使用export default 时,用import直接引入不用花括号;
如果export 时,则要使用花括号。

扩展:
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。CommonJS用于服务器,AMD用于浏览器。
①CommonJS:Node.js采用了这个规范。 根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。
②AMD(异步模块加载):但是Commonjs是同步加载模块,当要用到该模块了,现加载现用,这种同步机制到了浏览器里边就有问题了,性能问题。所以异步加载出现了,实现这种规范的js库是require.js。
语法:define 定义模块,require引入模块。

define({
    method1: function() {},
    method2: function() {},
});
require([module], callback);

Promise :

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
Promise是一个构造函数,用来生成promise实例,构造函数接收一个函数作为参数(执行函数),执行函数有两个参数(resolve和reject),当执行函数成功时执行resolve并将需要的参数传递出去,当执行函数失败时执行reject并将需要的参数传递出去。当实例生成后,可以用这个实例的then方法来指定成功和失败时的回调函数。

下面是一个用Promise对象实现的 Ajax 操作的例子:

const getJSON = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();
  });
  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出错了', error);
});

Promise.all()和Promise.race()
all方法接收一个promise数组([p1,p2,p3]),将其包装成一个新的promise对象p,当p1,p2,p3都是成功状态时,将p的状态变为成功状态,而race方法则是只要有一个promise对象返回成功,p就会变为成功状态。
想到最近使用的promise的实例代码如下:

//使用promise依次获取完三种筛选项后,一起渲染一次
        let this_=this;
        let role=new Promise(function (resolve,reject) {
            let url=urlConfig.queryFilterManageItemDetails+this_.state.websiteId+"/1";
            let headers={
                'accessToken': this_.state.accessToken
            };
            let params={};
            ajax.post(url,params,function (data,total) {
                resolve(data.list);
            },headers)
        });
        let business=new Promise(function (resolve,reject) {
            let url=urlConfig.queryFilterManageItemDetails+this_.state.websiteId+"/2";
            let headers={
                'accessToken': this_.state.accessToken
            };
            let params={};
            ajax.post(url,params,function (data,total) {
                resolve(data.list);
            },headers)
        });

        Promise.all([role, business]).then(function (results) {
            console.log(results);//results是个数组,数组项为两个promise成功返回的值
            this_.setState({
                filterRoleList:results[0],
                filterBusinessList:results[1]
            })
        });

async/await(拓展内容ES7,async/await同步代码的方式实现异步)

async用来定义个异步函数,返回一个promise对象
当async函数中return一个值时,这个值就是Promise对象中resolve的值,
当async函数中throw一个值时,这个值就是Promise对象中reject的值。
实例如下:

async function imAsync(num) {
  if (num > 0) {
    return num // 这里相当于resolve(num)
  } else {
    throw num // 这里相当于reject(num)
  }
}

imAsync(1).then(function (v) {
  console.log(v); // 1
});

// 注意这里是catch
imAsync(0).catch(function (v) {
  console.log(v); // 0
})

await 在async定义的函数里出现,暂停async函数的执行,等他后面的那个promise执行完成后,继续执行async函数内的下一行代码
注意:await不是谁都等,只等后面的promise,不是promise不等。
实例如下:

function timeout(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

async function asyncPrint(value, ms) {
    await timeout(ms);
    console.log(value);
}

asyncPrint('hello world', 50);

Class:

ES6 的类,完全可以看作是构造函数的语法糖(只是这样写,本质是一样的)。
下面看一下类的构造函数写法的不同:

//构造函数写法
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);

而使用ES6的类是这样写:

class Point {
     constructor(x,y){
            this.x=x;
            this.y=y;
     }
     toString(){
        return '(' + this.x + ', ' + this.y + ')';
     }
}

typeof Point // "function"
Point === Point.prototype.constructor // true

上面代码表明,类的数据类型就是函数,类本身就指向构造函数.
如果非要说区别,那就是ES6定义的类的原型上的方法是不可枚举的,也就是用Object.keys()遍历不到那个toString,而ES5的表现与之不同。

Class的继承

聊到ES6的继承,先回顾一下ES5的继承,介绍一下典型的构造函数继承,原型继承和组合继承。
首先,定义一个父类构造函数:

function Animal (name) {
  this.name = name || 'Animal';
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

继承方案一:构造函数继承

function Cat(){
      Animal.call(this);
}
let cat = new Cat();

特点:cat实例继承了Animal的构造函数里的属性和方法,但是没有继承原型上的方法。
继承方案二:原型继承

function Cat(){
}
Cat.prototype=new Animal();

特点:纯粹的原型继承,实例通过原型来查找属性和方法,如果父类中有引用类型的属性,子类实例修改这个属性时会影响到其他实例,因为他们共享这个引用类型的地址。

原型和原型链相关的介绍见:https://www.jianshu.com/p/a4e79a85dbf0

继承方案三:组合继承

function Cat(name){
    Animal.call(this);
}
Cat.prototype = new Animal();

特点:调用两次父类的构造函数,子类实例构造函数上的属性和方法将其原型的覆盖了。
继承方案四:寄生组合式继承

function inherit(Target,Origin) {//实现寄生组合式继承的核心函数
    function F() {};
    F.prototype = Origin.prototype; //F()的原型指向的是Origin
    Target.prototype = new F(); //Target的原型指向的是F()
    Target.prototype.constructor = Target; 
    Target.prototype.__proto__ == Origin.prototype
}

function Cat(name){
    Animal.call(this);
}

inherit(Cat,Animal);//实现寄生组合式继承

Class的继承
那么现在说Class的继承,是像这样写:

class Cat extends Animal{
      constructor(){
            super();
      }
}

而这个Class继承就可看作是寄生组合式继承的语法糖。

箭头函数

箭头函数写起来更加简洁,与普通函数的区别在于this的指向上。
this的指向:
①普通函数中的this指向undefined;
②对象方法中的this指向这个对象;
③构造函数中的this指向实例化的对象;
④箭头函数的this指向定义时的外层作用域的指向。

修改this指向:
call和apply都可以修改this指向并直接执行函数,但传参形式不同,apply第二个参数是数组;
bind和call传参形式相同,但bind可以延缓函数的执行;

ES6其他

①let/const 声明变量和常量;
②模板字符串,使用反引号内部用${}表示变量;
③解构赋值;
④函数默认参数,function(a=1){};

你可能感兴趣的:(ES6 核心总结)