JavaScript系列之ES6篇

Posted coderkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript系列之ES6篇相关的知识,希望对你有一定的参考价值。

八,Promise 异步

1,Promise 简介

(1)含义:

promise是ES6引出的新的异步编程的解决方案,语法上promise是一个构造函数,用来封装异步操作并且可以获取其成功或失败的结果。

2,简单的promise用例

 const p = new Promise(function(resolve,reject){//常用resolve和reject
        setTimeout(function(){
                let data = '数据库中的数据';
                resolve(data);//成功时的用例,返回data作为value
                let err = '数据读取失败';
                reject(data);//失败时的用例,返回data作为reason
        },1000)
 });

 p.then(function(value){//常用value和reason
        console.log(value);
 },function(reason){
        console.error(reason);
 })

3,链式编程

  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('one');
    }, 1000);
  }).then((data) => {
    console.log(data);
    return new Promise((resolve) => {     //  then方法的返回结果是一个promise对象
      setTimeout(() => {
        resolve('two');
      }, 1000);
    }).then((data) => {
      console.log(data);
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve('tree');
        }, 1000);
      }).then((data) => {
        console.log(data);
      });
    });
  });

4,promise.all()

 //需要发送两次请求
      Promise.all([
        new Promise((resolve, reject) => {
          $.ajax({
            url: 'url2',
            success: function (data) {
              resolve(data);
            },
          });
        }),
        new Promise((resolve, reject) => {
          $.ajax({
            url: 'url2',
            success: function (data) {
              resolve(data);
            },
          });
        }),
      ]).then((results) => {
        console.log(results);
      });

5,Promise.resolve()

const jsPromise = Promise.resolve('123');
// 上面代码将123转为一个 Promise 对象。

//  Promise.resolve等价于下面的写法。

Promise.resolve('123')
// 等价于
new Promise(resolve => resolve('123'))

6,promise.reject()

// promise.reject方法也会返回一个新的Promise实例,该实例的状态为rejected。

 var p = promise.reject("出错了");
 =>
 var p = new Promise((resolve,reject)=>reject('出错了'));

7,promise中的catch方法

const p = new Promise(function(resolve,reject){//常用resolve和reject
        setTimeout(function(){
                let data = '数据库中的数据';
                resolve(data);//成功时的用例,返回data作为value
                let err = '数据读取失败';
                reject(data);//失败时的用例,返回data作为reason
        },1000)
 });
 
 p.then(function(value){//常用value和reason
        console.log(value);
 }).catch(function(reason){
        console.error(reason);  // 失败时候回调
 })

8,promise封装jq的ajax

var p = new Promise((resolve, reject) => {
        $.ajax({
          type: method,
          url,
          data,
          dataType: "json",
          success: (res) => {
            resolve(res)
          },
          error: (err) => {
            reject(err)
          }
        })
      })
      
p.then(function(value){//使用then方法进行对promise对象的状态
        console.log(value);
 },function(reason){
        console.error(reason);//使用error在控制台进行警告
 })

九,ES6 module

1、介绍

历史上,javascript一直没有模块(modules)体系,无法将一个大程序拆分成互相依赖上午小文件,再用简单的方法拼接装起来。
在ES6之前,社区制定了一些模块加载方案,最主要的有CommonJSAMD两种。前者用于服务器,后者用于浏览器。
ES6在语言标准的层面上,实现了模块功能,而且实现的相当简单,完全可以取代CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。

2、export命令

模块功能主要由两个命令构成:export和import
export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。
如果你希望外部能够读取模块内部的某个变量,就必须适应使用export关键字输出该变量。下面使用export命令输出变量。

var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
function multiply(x,y){return x * y;};
export{firstName,lastName,year,multiply};

// 需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,
不能直接导出一个值。

export var m = 1;
      =>
var m = 1; 
export{m};
	=>
var m = 1; 
export{m as n};
// 在一个模块中,export可以调用多次。

3、import命令

使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块。

(1)解构导入

  import {firstName,lastName,year} from './profile';

(2)重命名变量

   import {lastName as surname} from './profile';

(3)重复导入

   import {name} from './module1';
    import {age} from './module1';
   // 如果多次重复执行同一import语句,那么只会执行一次模块代码。

(4)模块的整体加载

import * as persom from './module1';    

4、export default命令

使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。就要用到export
default命令为模块指定默认输出。

// 默认导出
export default function(){
    console,log('foo');
}

// 其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

import customName from './export-default';
customName(); //'foo'

export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,
因此export default命令只能使用一次。所以,import命令后面才不用加大括号,
因为只可能对应一个方法或者对象。

5、export与import的复合写法

// 如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。

export {foo,bar} from './my_module';
=>
import {foo,bar} from 'my_module';
export {foo,bar};

十,Class 类

1,ES6 中的类和对象

1.1,概念

(1)含义:

在ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。
类抽象了对象的公共部分,它泛指某一大类(class)。
对象特指某一个,通过类实例化一个具体的对象。

(2)特点:

① 抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)
② 对类进行实例化,获取类的对象。

1.2,创建类

(1)语法:

class Name {
// class body
}

(2)创建实例:

  var  变量名 = new name( );

(3)注意:

类必须使用 new 实例化对象。

(4)例如:

  // 1,创建类 class 
     class  Star {
     //代码
    }
   // 2,利用类创建对象 new
   new  Star( );

1.3,类 constructor 构造函数

(1)含义:

constructor( ) 方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过 new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor( )

(2)例如:

   // 1,创建类 class 
     class  Star {
                constructor(uname, age) {
                     this.name = uname;
                     this.age = age;
               }
       }
   // 2,利用类创建对象 new
   var  ldh =  new  Star('刘德华', 20 );
   var  zxy =  new  Star('张学友', 18);
   console.log(ldh.name);    //  刘德华    
   console.log(zxy.age);    //  18  

(3)注意:

1,通过 class 关键字创建类,类名我们还是习惯性定义首字母大写。
2,类里面有个 constructor 函数,可以接受传递过来的参数,同时返回实例对象。
3,constructor 函数,只要 new生成实例时,就会自动调用这个函数,如果不写这个函数,类也 会自动生成这个函数。
4,生成实例 new 不能省略。
5,创建类,类名后面不加小括号。生成实例,类名后面加小括号,构造函数不需要加 function

1.4,类中添加共有方法

(1)例如:

  <script>
       // 1,创建类 class
        class Star {
                   constructor(uname, age) {
                        this.name = uname;
                        this.age = age;
                  }
                  sing(song) {
                    console.log(this.name + song);
                  }
          }
      // 2,利用类创建对象 new
      var ldh =  new  Star('刘德华', 20 );
      var zxy =  new  Star('张学友', 18);
      console.log(ldh.name);    //  刘德华
      console.log(zxy.age);    //  18
      ldh.sing('冰雨');
    </script>

    <script>
class Fn {
  constructor() {
    // ...
  }

  add() {
    // ...
  }

  sub() {
    // ...
  }
}

// 等同于

Fn.prototype = {
  constructor() {},
  add() {},
  sub() {},
};
// 构造函数的prototype属性,在 ES6 的“类”上面继续存在。
// 事实上,类的所有方法都定义在类的prototype属性上面。
   </script>

(2)注意:

1,类里面所有的函数不需要写function
2,多个函数方法之间不需要添加逗号分隔。

2,类的继承

2.1,类继承 extends

(1)含义:

子类可以继承父类的一些属性和方法。

(2)语法:

class Father {
// 父类
}
class Son extends Father {
// 子类继承父类
}

(3)例如:

 <script>
      class Father {
        constructor( ) { }
        money( ) {
          console.log(100);
        }
      }
      class Son extends Father { }
      var son = new Son( );
      son.money( );
  </script>

2.2,super 关键字

(1)含义:

super 关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。

(2)例如:

 <script>
      class Father {
        constructor(x, y) {
          this.x = x;
          this.y = y;
        }
     // 父类中的this指向的是父类构造函数创建的实例对象
     // 因为父类中的函数所访问的变量是在父类的实例对象身上去找的,
     // 所以子类若想在调用的父类的方法中使用自身的变量,则需要通过super调用父类构造函数将
    其值传入父类中。
        sum( ) {
          console.log(this.x + this.y);
        }
      }
      // 关键字extends
      class Son extends Father {
        constructor(x, y) {
          // 通过super调用父类的构造函数
          super(x, y);
        }
      }
      var son = new Son(1, 2);
      var son2 = new Son(2, 3);
      son.sum( );    // 3
      son2.sum( );    // 5
      // 可能出现的报错:
      // ReferenceError: Must call super constructor in derived class before accessing 'this'
      or returning from derived constructor
      // 翻译: 当在访问this或在子构造函数return之前, 必须在子构造函数中先调用super构造函
        数。
      // 解释:在子类访问this或在子类的构造函数返回实例对象前,必须调用super父类构造函数
     </script>

    <script>
        // super 关键字调用父类普通函数
        class Father {
            constructor( ) { }
         say( ) {
           // console.log('this is father'); 
           return "this is father";
         }
       }
       class Son extends Father {
        constructor( ) {
          super( );
        }
        say( ) {
          console.log(super.say( ) + " this is son"); //在console代码中打印某函数的结果时,应该
      采用return的方式返回数据,而不应该在原函数中打印,这是错误的编程方式
        }
      }
      var son = new Son();
      son.say();
      // 若父类和子类含有相同的函数,则会应用就近原则,优先调用子类的函数。
    </script>

   <script>
      class Father {
        constructor(x, y) {
            this.x = x
            this.y = y
        }
        sum() {
            console.log(this.x + this.y);
        }
    }
    class Son extends Father {
        constructor(x, y) {
            super(x, y);  // super 必须在子类 this 之前调用
            this.x = x   // 这两句可以省略
            this.y = y
        }
        subtract() {
            console.log(this.x - this.y);
        }
    }
    var son = new Son(4, 5)
    son.subtract();   //-1
    son.sum();    //9
    </script>

(3)注意:

1,子类在构造函数中使用super,必须放到 this 前面(必须先调用父类构造方法,再使用子类构造方法)
2,es6中类没有变量提升,必须先定义类,再创建实例对象。
3,类中的共有属性和方法在访问时必须加 this


以上是关于JavaScript系列之ES6篇的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript系列之ES6篇

JavaScript系列之高级篇

ES6系列之开发环境搭建

JavaScript系列之基础篇

狙杀ES6之开光篇

ES6 从入门到精通系列学习笔记 23 篇(完结)