# ES6

ES6

介紹

ES6是ES5的升級版,兼容ES5和ECMAScript,新增了許多新特性,例如:解構、異步函數、承諾……,語法簡單,功能更強。可是ES6在瀏覽器上兼容性差一些,在nodejs上能夠徹底兼容。

環境(node.js)

$ node -v 檢測環境
$ v10.14.2 當前環境
  1. 安裝vi及spf-13javascript

    $ vi demo.js
  2. 安裝node.js
    Linux
    先將安裝包解壓
    而後進行環境變量的配置便可
    windows
    直接點擊安裝便可
  3. REPL環境css

    $ node
    1+1

新特性

例如:vue

['terry','larry','tom'].forEach((item)=>{console.log(item)})
terry
larry
tom
undefined

模塊化 (xxx.js上分模塊)

ES6---babel/webpack(js插件運行在node.js上)--->ES5
es6執行原理.png
區分:
dom驅動:~~~~
含義:經過ajax獲取數據,建立結構,再將數據填充
真實dom機制,先渲染dom節點,再經過js操做dom
<div class="a">
數據驅動:(vue)
含義:來源於後臺數據,經過ajax獲取數據,建立虛擬dom節點,追加到頁面中
虛擬dom機制,經過js建立一個dom
$(<div class="a"></div>).appendTo($('body'))
高級腳本語言
<script>
jsx(javascript xml)
less/sass
</script>java

模塊化結構
Node.js採用模塊化結構,按照 CommonJS 規範定義和使用模塊。在Node中,以模塊爲單位劃分全部功能,而且提供一個完整的模塊加載機制,使得咱們能夠將應用程序劃分爲各個不一樣的部分,而且對這些部分進行很好的協同管理。經過將各類可重用的代碼編寫在各類模塊中的方法,咱們能夠大大減小應用程序的代碼量,提升應用程序開發效率以及應用程序的可讀性。經過模塊加載機制,咱們也能夠將各類第三方模塊引入到咱們的應用程序中。
其意圖是應用程序開發人員可以使用CommonJS API編寫應用程序,而後在不一樣的JavaScript解釋器和主機環境中運行該應用程序。在兼容CommonJS的系統中,你可使用 JavaScript程序開發。

模塊定義:一個單獨js文件,或一個目錄,目錄的嵌套也能夠是一個模塊node

模塊做用域:每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見
。若是想在多個文件分享變量,必須定義爲global對象的屬性。jquery

模塊交互:每一個模塊內部,module變量表明當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,實際上是加載該模塊的module.exports屬性。
定義模塊:module.exports.x = x;
模塊加載:var example = require('./example.js'); webpack

node_modules 是一個目錄,用於存放第三方模塊
module變量ios

在任意一個js文件中,都包含一個變量叫module,module表示當前模塊的一些信息
id
filename     完整路徑+文件名
paths         require的時候去哪裏尋找要加載的模塊,當前模塊node_modules-->上級模塊node_modules
parent         父模塊
children     子模塊~~~~
exports     對外暴露的對象,require當前模塊實際上就是require這個exports對象

require()es6

用於加載其餘模塊
1) 參數爲路徑
    require('./module1')
    按照指定路徑加載須要的模塊
2) 參數爲模塊名稱
    require('module1')
    按照module.paths中指定的路徑尋找該模塊

模塊做爲一個目錄web

>$ mkdir module
>$ cd module
>$ npm init/npm init -y將該目錄初始化爲一個node模塊,產生一個package.json文件

npm ——node的模塊管理機制(node package manager

npm init )

Npm是的Js開發者可以更方便的分享和複用以及更新代碼,被複用的代碼被稱爲包或者模塊,一個模塊中包含了一到多個js文件。在模塊中通常還會包含一個package.json的文件,該文件中包含了該模塊的配置信息。一個完整的項目,須要依賴不少個模塊。

1.將當前目錄初始化爲一個node模塊

$ npm init -y
$ npm install xxx

2.安裝第三方模塊xxx,局部安裝,將第三方依賴默認安裝到當前目錄的node_modules中

$ npm install jquery --save(默認)
$ npm install jquery -S(默認)
--save表示將模塊安裝到當前目錄的node_modules;將這個依賴的信息添加到package.json中dependencies屬性中,dependencies中的依賴爲產品依賴
-S, –save 
-D, --save-dev: Package will appear in your devDependencies.

從node_modules中刪除不須要的模塊

$ npm uninstall -g <package_name>

$ npm install babel --save-dev

devDependencies 開發依賴,只在產品開發階段纔會使用到,在產品階段無需這些依賴

npm install xxx -g
-g 全局安裝,將第三方依賴安裝

$NODE_HOME/lib/node_modules
$NODE_HOME/bin
$NODE_HOME/share

詳見:npm中文文檔
cnpm.png

安裝babel命令行轉碼

做用:將es6轉換爲es5,可是注意一點:若是你寫的js代碼運行在nodejs(如:服務器,插件)上無需轉換;後期運行在瀏覽器上作dom操做的代碼須要轉換。
    1. 安裝babel
        >$ cnpm install -g babel-cli
        >$ babel --version
    2. 本地安裝預設(當前產品目錄下安裝)
        >$ cnpm install --save-dev babel-preset-es2015

ES2015轉碼規則
$ npm install --save-dev babel-preset-es2015 =>es2015

3.安裝預設而且添加配置文件配置.babelrc

在當前項目的根目錄下建立該文件

>$ npm install --save-dev babel-preset-es2015
        { 「presets」: [ "es2015"]} 
    4.運行babel xxx.js

babel-polyfill 墊片
產生緣由:Babel 默認只轉換新的 JavaScript 句法,而不轉換新的 API
1.安裝墊片

$ npm install --save babel-polyfill

2.在js文件中引用而且使用
import 'babel-polyfill'; // 或者 require('babel-polyfill');

安裝cnpm淘寶鏡像
$ npm install -g cnpm --registry=https://registry.npm.taobao.org

報錯:
EACCES: permission denied, access '/opt/node-v10.14.2/lib/node_modules/cnpm/node_modules/address'
報錯緣由是由於當前用戶是普通用戶,普通用戶不容許操做非家目錄

解決方案:
1) sudo
2) 將/opt/node-v10.14.2/lib/node_modules,/opt/node-v10.14.2/bin,/opt/node-v10.14.2/share 這三個目錄的擁有者設置爲當前用戶

//$ echo $(whoami) 查看當前用戶

//$ echo $(npm config get prefix) 查看操做的文件
$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

$ cnpm -v 查看npm版本

基礎知識

* let聲明

·es5中 var變量聲明
1)能夠重複聲明 2)變量聲明會被提高 3)沒有局部做用域
·let變量聲明
1)不能夠重複聲明 2)變量聲明不會被提高 3)具備局部做用域

·聲明常量 const
特色:1)不能夠重複聲明 2)變量聲明不會被提高 3)具備局部做用域 4)常量的值沒法改變
例:const qs =require('qs');

·解構(模式匹配):能夠一次性從對象或數組中獲取多個值,並把這些值賦值給不一樣變量
1)對象解構

let {name,age:gender} = {name:"terry",age:12}
let obj = {
    realname:"terry",
    address:{
        province:"山西省",
        city:"太原市",
        area:"尖草坪"
    }
}
let {realname,address:{city}} = obj;

2)數組解構

//let [a,b,c] = [8,2,5];
    let [a,a1,a2,[b,b2,b3]] = [8,2,5,[12,3],4];
    console.log(a,b,b3);

3)字符串解構
解構時,字符串被轉換成了一個相似數組的對象。
const [a, b, c, d, e] = ‘hello’;//a=h;b=e;c=l;d=l;e=o 對數組的屬性解構
let {length : len} = ‘hello’; //len = 5
4)解構默認值

默認值(默認值生效的條件是,對象的屬性值嚴格等於undefined)
let {name,gender="male"}={name:"terry",age:12,gender:"female"};

console.log(name,gender);
function ajax({url,method="get",data={},success}){
console.log('url',url);
    console.log('method',method);
    console.log('data',data);
    console.log('success',success);
}
ajax({
    url:"http://www.baidu.com/",
    method:"post",
    success:function(){

    }
})

* 對象拓展~~~~

  1. 對象簡寫
    ·屬性簡寫
    ES6容許直接寫入變量和函數,做爲對象的屬性和方法。這時,屬性名爲變量名, 屬性值爲變量的值。
let name = "terry",
let age = 12;
let sayName = function(){
    console.log(this.name);
}
        let obj  = {name, age ,sayName}
        =>
        let obj  = {name:name, age:age ,sayName:sayName}
        =>
        let obj  = {
            name:"terry", 
            age:12 ,
            sayName:function(){
                console.log(this.name);
            }
        }

·方法簡寫

var o = { method() { return "Hello!"; } }; 
=> 
var o = { method: function() { return "Hello!"; } };

2.對象api擴展
·Object.xxx
注意:一個實例能夠調用該實例構造函數原型的方法
`var o =new Object();//o爲實例;

Object爲構造函數;
                Object.prototype爲構造函數原型`

·Object.is(val1,val2)

相似於===,對比值相等

·Object.assign(target,o1,o2……)

用於對象的合併,將源對象的全部可枚舉屬性,複製到目標對象(target)。 Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,若是源對象某個屬性的值是對象,那麼目標對象拷貝獲得的是這個對象的引用,而不是值的引用。
let o ={sayname(){},sayage(){}}
let b ={sayhello(){}}
Object.assign(o,b)
{ sayname: [Function: sayname],
sayage: [Function: sayage],
sayhello: [Function: sayhello] }
o
{ sayname: [Function: sayname],
sayage: [Function: sayage],
sayhello: [Function: sayhello] }
將o,b中可枚舉的屬性合併到target中,返回target,用於對象克隆

·Object.setPrototypeOf(obj,prototype)
爲obj對象指定一個新的原型等價於 obj.__proto__= prototype
·Object.getPrototypeOf(obj)
獲取obj對象的原型也就是其構造函數的原型

let o = new Object();
o.__proto__ ===Object.prototype
true
o.__proto__ ===Object.getPrototypeOf(o)
true

·Object.keys(obj)
返回一個數組,成員是參數對象自身的(不含繼承的)全部可遍歷屬性的鍵名。
·Object.values(obj)
返回一個數組,成員是參數對象自身的(不含繼承的)全部可遍歷屬性的鍵值
·Object.entries(obj)
返回一個數組,成員是參數對象自身的(不含繼承的)全部可遍歷屬性的鍵值對數組。

let o = {name:"terry",age:12}
Object.keys(o)
[ 'name', 'age' ]
Object.values(o)
[ 'terry', 12 ]
Object.entries(o)
[ [ 'name', 'terry' ], [ 'age', 12 ] ]

* 函數拓展~~~~

  1. 函數簡寫
    函數聲明在對象中
let obj = {
            sayName(){
                console.log(this.name);
                }
            }
==>
let obj  = {
            sayName:function(){
                console.log(this.name);
                }
            }

函數聲明在參數中(回調函數)【箭頭函數】
通常爲匿名函數
注意:箭頭函數this的取值爲該箭頭函數外部函數的this,若是沒有外部函數,就指向全局對象,儘可能避免var a = (item)=>{return xxx}
1)極簡模式
item表示形參,xxx爲返回結果(方法體中只有這一個表達式)

item=>xxx
等價於
function(item){return xxx}
let arr =[{
    name:"terry",
    gender:"male"
},{
    name:"vicky",
    gender:"female"
},{
    name:"larry",
    gender:"male"
}]
/*
let result = arr.filter(function(item){
    return item.gender ==="male"
})*/
let result = arr.filter(item=>item.gender === "male")
//從一個數組中篩選出知足條件的值
console.log(result);

2)普通模式
當方法體中有多個表達式,方法體必定要加大括號
當形參有多個的時候,參數必須加小括號

let result = arr.filter((item,index)=>{console.log(index);
return item.gender ==='male'
})

3)this指向

let obj ={
    data:{
        name:"one",
        list:[1,2,3,4]
    },
    foo(){
       /*
       另外一種方法:回調函數的this指向global,而咱們須要訪問obj對象,因此提早先將obj保存到變量o中
        let o = this
        this.data.list.forEach(function(item){
            console.log(o.data.name)
        })*/
        //箭頭函數this指向其外部函數的this即obj
       this.data.list.forEach((item)=>{
           console.log(this.data.name);
    })
}
}
obj.foo();

知識點:rest操做符(...),具備剝離拆分效果,能夠將字符串變爲數組

let s = "hello wrold"
'hello wrold'
let arr = [...s]
[ 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'r', 'o', 'l', 'd' ]
s.split("")
[ 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'r', 'o', 'l', 'd' ]

* 數組拓展~~~~

  1. 數組建立方式
    [...string];//rest建立
    new Array(3);//長度爲3的數組
    new Array(3,2);//數組初始化
    ·數組新特性
    Array.from 用於將兩類對象轉爲真正的數組:相似數組的對象(array-like object)和可遍歷(iterable)的對象(包括ES6新增的數據結構Set和Map)
    以前講過:類數組對象到數組的轉換 Array.prototype.slice.call(array-like,0)
let Arraylike ={"0":"terry","1":"larry",length:2}//建立類數組對象
//Arraylike[0];//訪問第一個元素,不能夠調用push()
console.log(Arraylike);
//從數組對象中解構出slice方法
let {slice}=[];

// 原始轉換方法 let array = Array.prototype.slice.call(Arraylike,0);
let array=slice.call(Arraylike,0);
//使用Array.from轉換
console.log(array);
console.log(Arraylike);
console.log(Array.from(Arraylike));
let set = new Set([1,2,3,4,1,2,3,4]);
//使用Array.from轉換可遍歷對象
console.log(set);
console.log(Array.from(set));
//例如:字符串去重
> new Set("hello")
Set { 'h', 'e', 'l', 'o' }
> Array.from(new Set("hello"))
[ 'h', 'e', 'l', 'o' ]
> Array.from(new Set("hello")).join()
'h,e,l,o'
>[...new Set("hello")]
 ['h','e','l','o']

2.**Array.of(p1,p2,…)** 
用於將參數中元素轉換爲數組,放入初始化數組
主要目的是彌補數組構造函數Array()的不足。由於參數個數的不一樣,會致使Array()的行爲有差別。
Array.of(3, 11, 8) // [3,11,8]  

3.Array.prototype.includes()
    該方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes方法相似
>[1, 2, 3].includes(2);         // true 
>[1, 2, 3].includes(4);         // false 
>[1, 2, NaN].includes(NaN);     // true

4.Array.prototype.find()/Array.prototype.findIndex()
數組實例調用
    數組實例的find方法,用於找出第一個符合條件的數組成員。它的參數是一個回調函數,全部數組成員依次執行該回調函數,直到找出第一個返回值爲true的成員,而後返回該成員。若是沒有符合條件的成員,則返回undefined 。find方法的回調函數能夠接受三個參數,依次爲當前的值、當前的位置和原數組。相似於filter()方法
    數組實例的findIndex方法的用法與find方法很是相似,返回第一個符合條件的數組成員的位置,若是全部成員都不符合條件,則返回-1。

let arr=[{name:'terry',age:12},

{name:'tom',age:12},
{name:'larry',age:22},
{name:'vicky',age:22}];

~~let result = arr.find(function(item){return item.age===12})//es5方法~~
let result = arr.find(item=>item.age===12);~~~~
let result1= arr.findIndex(item=>item.age===12);
console.log(result,result1);

5. Array.prototype.fill()  用於填充數組值
   > new Array(3).fill(7); // [7, 7, 7]

6.Array.prototype.keys()/values()/entries()
用於遍歷數組,返回值爲一個迭代器對象(經過For-of進行遍歷可遍歷的對象)
它們都返回一個遍歷器對象(詳見《Iterator》一章),能夠用for...of循環進行遍歷,惟一的區別是keys()是對鍵名的遍歷,返回遍歷索引迭代器,entries()是對鍵值對的遍歷,返回遍歷數組key-val迭代器,values()是對鍵值的遍歷,返回遍歷數組元素迭代器,
> let arr = ['terry','larry','tom']
> arr
[ 'terry', 'larry', 'tom' ]
> for(var key in arr){console.log(arr[key])}
terry
larry
tom
undefined
> let iterator = arr .values()
> iterator
Object [Array Iterator] {}
> iterator.next()
{ value: 'terry', done: false }
> iterator.next()
{ value: 'larry', done: false }
> iterator.next()
{ value: 'tom', done: false }
> iterator.next()
{ value: undefined, done: true }

使用迭代器:

let arr =["terry","larry","tom","vicky"];
//獲取迭代器
let values_iterator = arr.values();
//經過迭代器獲取數組元素
let item;
while(!(item = values_iterator.next()).done){

console.log(item.value);

}
//使用for-of遍歷迭代器
let entry_iterator = arr.entries();
for(let entry of entry_iterator){

console.log(entry);

}
//使用for-of遍歷數組
for(let item of arr){

console.log(item);

}
//若是爲for-in則返回值爲索引~~~~

### 集合api

##### 1. Set
  無序不可重複的集合(數組中元素能夠有序重複)
  它相似於數組,可是成員的值都是惟一的,沒有重複的值。Set 自己是一個構造函數,用來生成 Set 數據結構。
    1)實例化Set對象
    let set = new Set();
    let set = new Set([1,2,3,12,3]);
    2)經過api訪問,Set.prototype.xxx
     **屬性**
     Set.prototype.size 返回Set集合中元素的個數
     **方法**
     add(val) 向集合中添加value
     delete(val) 從集合中刪除value
     has(val) 判斷集合中是否存在value
     clear() 清空
     forEach() 迭代
     keys()  獲取迭代器對象
     values() 獲取迭代器對象
     entries() 獲取迭代器對象
     
> let s = new Set(["terry","larry","tom"])
Set { 'terry', 'larry', 'tom' }
> s.keys()
[Set Iterator] { 'terry', 'larry', 'tom' }
> s.values()
[Set Iterator] { 'terry', 'larry', 'tom' }
    
    因此,Set集合沒有索引,keys()與values()返回值相等
例子以下:
s.forEach(item=>{console.log(item)})
terry
larry
tom
undefined
for(let s1 of s){console.log(s1)}
terry
larry
tom
undefined
for(let s1 of s.values()){console.log(s1)}
terry
larry
tom
undefined
for(let s1 of s.entries()){console.log(s1)}
[ 'terry', 'terry' ]
[ 'larry', 'larry' ]
[ 'tom', 'tom' ]
undefined
s.add("vicky")
Set { 'terry', 'larry', 'tom', 'vicky' }
s.delete("vicky")
true
s
Set { 'terry', 'larry', 'tom' }
s.has("tom")
true
s.clear()
Set {}
##### 2. Map
   Map相似於對象,也是鍵值對的集合,Object 結構提供了「字符串—值」的對應,Map結構提供了「值—值」的對應,對於Map而言,key值能夠爲任意數據對象;但對於對象而言,key值必須是字符串
  1)實例化Map對象
    let map = new Map();
    let map = new Map([key,value],[key,value]);
    
如何將對象轉換爲Map?

let obj = {

name:"terry",
age:12

}
let map = new Map(Object.entries(obj));
console.log(map);

2)經過api訪問,Map.prototype.xxx     
 **屬性**
 Set.prototype.size 返回Map中鍵值對個數
 **方法**
 set(key,value) 向map中設置鍵值對,key不能夠重複,若是重複,value更新
 get(key) 經過key獲取value
 has(key) 判斷map集合中是否存在指定的key
 delete(key) 經過key從map集合中刪除
 clear() 清空map集合
 keys() 返回迭代器對象
 values() 返回迭代器對象
 entries() 返回迭代器對象
 
  ##### 3. Iterator迭代器
  
   Iterator的做用:一是爲一切可迭代的對象,提供一個統一的、簡便的訪問接口;二是使得數據結構的成員可以按某種次序排列;三是ES6創造了一種新的遍歷命令for...of循環(for…of能夠迭代可迭代的對象和迭代器對象)。
   iterator能夠調用指針對象的next()方法,能夠將指針指向數據結構的第一個成員{value:done;}
   原生具有 Iterator 接口的數據結構以下:
        Array
        Map
        Set
        String
        TypedArray
        函數的 arguments 對象
        NodeList 對象
iterator接口如何附着在對象上?
   經過Symbol()機制產生一個不會衝突的變量,這個變量用於向對象中插入一個屬性而不對對象中其餘屬性形成影響。s.[Symbol.iterator]();
   
//經過數組迭代器遍歷
> let iterator_arr=arr[Symbol.iterator]()
undefined
> iterator_arr
Object [Array Iterator] {}
> iterator_arr.next()
{ value: 'terry', done: false }
> iterator_arr.next()
{ value: 'larry', done: false }
> iterator_arr.next()
{ value: undefined, done: true }

//經過字符串迭代器遍歷
> let  str = "hello"
undefined
> let iterator_str=str[Symbol.iterator]()
undefined
> iterator_str
Object [String Iterator] {}
> iterator_str.next()
{ value: 'h', done: false }
> iterator_str.next()
{ value: 'e', done: false }
> iterator_str.next()
{ value: 'l', done: false }
> iterator_str.next()
{ value: 'l', done: false }
> iterator_str.next()
{ value: 'o', done: false }
> iterator_str.next()
{ value: undefined, done: true }

//for-of遍歷數組
>let arr = ["terry","larry","tom"]
undefined
> for(let s of arr.values()){console.log(s)}
terry
larry
tom
undefined
> for(let s of arr){console.log(s)}
terry
larry
tom
undefined
   
##### 4. Promise承諾對象,用於封裝異步操做
   所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理
    有了Promise對象,就能夠將異步操做以同步操做的流程表達出來,避免了層層嵌套的回調函數。
`
<script>
//不穩定
    $.get("http://134.175.100.63:6677/customer/findAll",function(result){
        console.log(result);//後打印,請求發出後臺運行

    $.get("http://134.175.100.63:6677/order/findAll",function(result){
        console.log(result);//回調函數嵌套一個異步函數,產生回調噩夢
            });
        });
        console.log("end");//先打印
    </script>
`
   Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。
    resolve函數的做用是,將Promise對象的狀態從「未完成」變爲「成功」(即從 Pending 變爲 Resolved),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去;reject函數的做用是,將Promise對象的狀態從「未完成」變爲「失敗」(即從 Pending 變爲 Rejected),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。若是調用resolve函數和reject函數時帶有參數,那麼它們的參數會被傳遞給回調函數。

   1. 實例化一個Promise對象
let promise = new Promise(function(resolve,reject){
    //包含異步操做
    1)當異步操做成功的時候執行resolve(),就能夠將承諾的狀態由pending -> resolved
    2)當異步操做失敗的時候執行reject(),就能夠將承諾的狀態由pending -> rejected
        })

   當promise實例產生,這個Promise中的回調函數就會執行。經過then方法監聽承諾對象狀態的改變
   
   2.Promise.prototype.then()
    Promise 實例具備then方法,它的做用是爲 Promise 實例添加狀態改變時的回調函數。then方法的第一個參數是Resolved狀態的回調函數,第二個參數是Rejected狀態的回調函數。
   then(resolved_callback,rejected_callback)
    resolved_callback 當承諾對象狀態 pending -> resolved
    rejected_callback 當承諾對象狀態 pending -> rejected
    catch(rejected_callback)
    rejected_callback 當承諾對象的狀態pending -> rejected
    不論是ajax交互中出現的40四、500異常會被catch捕獲,在then中的代碼語法錯誤也會被catch捕獲
    finally(callback)
    無論承諾的狀態最終如何,該函數中的回調函數都會執行,通常用於關閉加載狀態~~~~
    
   3.Promise.all()
   用於將多個Promise實例,包裝成一個新的Promise實例。即將多個承諾對象合併爲一個
  ` let promise = Promise.all([p1,p2,p3]);`
  p的狀態由p1,p2,p3決定,當p1,p2,p3所有成功執行纔會執行.then();只要p1,p2,p3其中一個失敗,執行.catch();
  
  4.Promise.race() 隨機狀態
   用於將多個Promise實例,包裝成一個新的Promise實例。即將多個承諾對象合併爲一個
  ` let promise = Promise.race([p1,p2,p3]);`
    p的狀態由p1,p2,p3決定,只要p1,p2,p3其中一個成功,就會執行.then(),p的狀態就會變爲resolve,此時狀態爲resolve的這個承諾就會將返回結果傳給p的回調函數;
    p的狀態取決於第一個狀態改變的那個承諾狀態
   5.Promise.resolve() 
   將現有對象裝換爲Promise對象,當參數是一個Promise實例,Promise.resolve將不作任何修改,返回這個實例;當參數對象具備.then()方法,Promise.resolve方法會將這個對象轉爲Promise對象。然會當即執行.then()方法;參數是不具備.then()方法的對象或根本不是一個對象,Promise.resolve返回一個新的Promise對象,狀態爲resolved
 `let p = Promise.resolve($_ajax);
  p.then((result)=>{return result})//參數爲一個ajax
 `
 `let obj = {
    name:"terry",
    then:function(){
        return "thenable"
    }
 }
 let p1 = Promise.resolve(obj);//將一個對象轉化爲一個Promise對象
 `
   6.Promise.reject()用於返回一個新的Promise實例,狀態爲rejcted~~~~
    
   7.Promise.any()
   接受一組Promise實例做爲參數,包裝成一個新的Promise實例。只要參數實例有一個編程resolve狀態,包裝實例就會變成resolve狀態;若是全部參數實例都變成rejected狀態,包裝實例就會變成rejected狀態。
  
  
 ##### 5. Generator函數 異步操做同步化(React-Redux-saga中普遍應用)
   一種異步編程的解決方案,它是一個普通函數,它有兩個特色:1)function關鍵字與函數名之間有個‘*’
   2)函數體內部使用yield表達式,產生不一樣的內部狀態,默認狀況下yield返回值爲undefined,yield '值';yield '函數調用';

//生成函數
function* helloGeneator(){
yield 'hello';
yield 'world';
return 'end';
}
let val = helloGenerator();//調用結果爲迭代器
iterator.next();

例子以下:

function* foo(){
    yield 'one';
    yield 'two';
    yield 'three';
    return 'end';
}
let result = foo();
//"hello"[Symbol.iterator]() 迭代器生成函數=> foo();
console.log(result.next());

console.log(result.next());

console.log(result.next());

console.log(result.next());//每次獲取一個迭代器
/*let item;
while(!(item=result.next()).done){
    console.log(item.value);
}*/

/*for(let r of result){
    console.log(r)
}*/

Generator函數應用

  1. 能夠生成迭代器對象
    let obj = {"0":"terry","1":"larry"};

=>obj[Symbol.iterator]=[][Symbol.iterator];//obj變爲可迭代對象

obj[Symbol.iterator]=迭代器生成函數

Q:如何將obj轉換爲一個可迭代對象?
A:

let obj={"0":"terry","1":"larry","2":"tom"};
let a ="3";
obj[a]="vicky";
obj[Symbol.iterator]= function* (){
    for(let k in obj){
        let val = obj[k];
        yield [k,val];
    }
}
obj.entries = obj[Symbol.iterator];
let iterator=obj.entries();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/*
for(let o of obj){
    console.log(o);
}*/
/*
var iterator=obj[Symbol.iterator]();
iterator.next();

iterator.next();
iterator.next();
iterator.next();*/

2.利用Generator實現異步操做同步化
重要案例以下:

<script>
    let $ = {
        // 基於promise的異步操做的封裝
         get(url){
            // 將異步操做封裝到一個承諾對象中
            return new Promise((resolve,reject)=>{
                let xhr = new XMLHttpRequest();
                xhr.open("GET",url);
                xhr.responseType = "json";
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
                xhr.send();
                xhr.onreadystatechange = function(){
                    if(this.readyState === 4){
                        if(this.status === 200){
                            // 承諾成功
                            resolve(this.response)
                        } else {
                            // 承諾失敗
                            reject(this)
                        }
                    }
                }
            })
        }
}

    /*異步操做
    $.get("http://134.175.100.63:6677/customer/findAll");
        .then((response)=>{
            console.log("customers:",response);
        })
        .catch(()=>{
            alert('異常')
        })
    $.get("http://134.175.100.63:6677/order/findAll");
        .then((response)=>{
            console.log("customers:",response);
        })
        .catch(()=>{
            alert('異常')
        })*/
    function* foo(){
        let c_url="http://134.175.100.63:6677/customer/findAll"
        let customers= yield call ($.get,c_url);
        console.log("customer:",customers);

        let o_url="http://134.175.100.63:6677/order/findAll"
        let orders= yield call($.get,o_url);
        console.log("order:",orders);

        let a_url="http://134.175.100.63:6677/address/findAll"
        let addresss= yield call($.get,a_url);
        console.log("address:",addresss);
    }    
    //異步函數執行器(再上一個請求結束後再去調用下一個請求;將當前請求結果做爲yield表達式返回)
    function call(handler,params){
        handler(params)
        .then((response)=>{            
            iterator.next(response)//參數會賦值給上個yield,也就是說,會做爲上一個yield表達式返回值 耦合性強,複雜
        })
    }
    // let iterator = foo();
    // iterator.next();
    //查詢顧客信息,根據id查詢地址信息
    function* bar(){
        let customers = yield call($.get,"http://134.175.100.63:6677/customer/findAll");
        console.log("全部顧客:",customers);
        let id =customers.data[0].id;
        let address=yield call($.get,"http://134.175.100.63:6677/address/findByCustomerId?id="+id);
        console.log("地址信息",id,address);
    }
    let iterator = bar();
    iterator.next();
</script>

異步操做同步化.png~~~~
能夠藉助第三方模塊co ,調用Generator函數

##### 6. Async函數 (Generator函數的語法糖)
用於異步函數的同步化

//vuex中使用
async function foo(){
    let customers = await $.get("http://134.175.100.63:6677/customer/findAll")
    console.log(customers);
let id = customers.data[0].id;
let addresses = await $.get("http://134.175.100.63/address/findByCustomerId?id"+id)
return [customers,addresses];
}
let f = foo();//返回Promise對象
f.then((result)=>{console.log(result)})

##### 7.axios 基於Promise的ajax框架
便可以運行在瀏覽器(封裝XMLHttpRequest),又能夠運行在node.js(封裝http)

  1. ajax
    1)XMLHttpRequest 不可使用任何框架完成異步請求
    2)JQuery.ajax 技術站:jquery,bootstrap,easyui,Echarts……
    3)axios 技術站:vue+vuex+vueRouter+element

2.原理
例如
` let $ = {

// 基於promise的異步操做的封裝
    get(url){
        // 將異步操做封裝到一個承諾對象中
        return new Promise((resolve,reject)=>{
            let xhr = new XMLHttpRequest();
            xhr.open("GET",url);
            xhr.responseType = "json";
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
            xhr.send();
            xhr.onreadystatechange = function(){
                if(this.readyState === 4){
                    if(this.status === 200){
                        // 承諾成功
                        resolve(this.response)
                    } else {
                        // 承諾失敗
                        reject(this)
                    }
                }
            }
        })
    }
}

`
3.導入方式
1)模塊化導入
cnpm install axios --save
2)script標籤導入
<script src="https://cdn.bootcss.com/axios...;></script>

4.底層接口
axios(config){
url,
method,
data,請求體參數(post)
params,請求行參數(get)
headers,默認爲json
transformRequest:[//多個匿名函數(data,headers)={
//將data轉換爲查詢字符串,qs庫
return data;
}],轉變請求,在請求發送到服務器端前容許對data進行處理,通常用於編碼
transformResponse:[(data)=>{
return data;
}],響應結果到達then、catch前進行處理,data爲後端返回的原始數據
responseType,默認爲json
baseUrl,//基路徑
timeout//請求超時最大時間
} ,返回值爲一個ajax承諾對象
paramsSerializer: function (params) {

return Qs.stringify(params, {arrayFormat: 'brackets'})序列化params爲查詢字符串,get參數拼接在瀏覽器地址欄URL後,只能爲查詢字符串

},
withCredentials:false,默認不攜帶cookie
}

let axios = require('axios');
let qs = require('qs');
//默認基路徑
axios.defaults.baseURL="http://134.175.100.63:6677"
axios.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded"
axios.defaults. transformRequest=[(data)=>{return qs.stringify(data)}]

function saveCustomer(){
    let data = {
        realname:"張三",
        telephone:"12344321"
    }
    axios({
        url:"/customer/saveOrUpdate",
        method:"post",
        data,
       
    })
    .then((response)=>{console.log(response.data)})
    .catch(()=>{console.log("error")})
function findAllCustomer(){
    axios({
        url:"/customer/findAll",
        method:"get"
    })
    .then((response)=>{console.log("顧客信息",response.data)})
}
saveCustomer();
findAllCustomer();

5.快捷接口
axios.get(url[,config])查詢
axios.post(url,data)保存
axios.delete(url[,config)刪除
axios.put(url,data)修改

  1. response
    1)response爲then回調函數中的參數,也就是axios的請求成功的結果 ,這個結果不是後臺返回的結果,而是二次封裝的對象
    .then((response)=>{})
    2)response架構
    {
    status,
    statusText,
    data,
    headers,
    config,
    request
    }

    1. axios默認配置

$.ajaxSetup(config)
axios.defaults用於保存默認配置信息,這個配置對全部axios對象產生影響
axios.daefaults.baseURL
axios.daefaults.timeout
axios.daefaults.transformRequest
axios.daefaults.transformResponse
axios.daefaults.headers.common
axios.daefaults.headers.post
axios.daefaults.headers.get

8.攔截器
攔截器.PNG
//請求攔截器
axios.interceptors.request.use(function(config){
//請求前執行代碼
return config;
},function(error){
return Promise.reject(error)
})
//響應攔截器
axios.interceptors.response.use(function(response){
//響應獲取後執行代碼
return response;
},function(error){
return Promise.reject(error)
})

//常見配置
let axios = require("axios")
let qs = require("qs")
// 配置默認基路徑
axios.defaults.baseURL = "http://127.0.0.1:6677";
// axios.defaults.baseURL = "http://134.175.100.63:6677";
axios.defaults.headers.common["Content-Type"] = "application/x-www-form-urlencoded"
axios.defaults.transformRequest = [(data)=>{
          return qs.stringify(data);
    }]
// 攔截器
        axios.interceptors.response.use(function(response){
            return response;
        },function(error){
     // 當任何一個ajax請求出現異常的話都會打印錯誤信息!
            console.log("error!!!");
            return Promise.reject(error);
        });

##### 8.Class es5中構造函數語法糖
JavaScript 語言中,生成實例對象的傳統方法是經過構造函數。 ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,做爲對象的模板。經過class關鍵字,能夠定義類。
類中能夠直接定義方法,實際上類的全部方法都定義在類的prototype屬性上面。在類的實例上面調用方法,其實就是調用原型上的方法。

|對比 |
| 構造函數 | 類 |
| `
//構造函數
function Animal(name){
this.name=name;
}
//原型
Animal.prototype.sayName=function(){

console.log("my name is",this name)

}

//繼承
function Dog(name,age){
//借用構造函數繼承
Animal.call(this.name)
this.age=age
}
//原型鏈繼承
Dog.prototype = new Animal();
Dog.prototype.sayAge = function(){
console.log("my age is",this.age);
}
let d = new Dog("多多",2);
d.sayName();
d.sayAge();
|
class Animal{
//構造函數
constructor(name){

this.name=name;

}
//普通函數
sayName(){

console.log("my name is",this.name);

}
}
//原型鏈繼承
class Dog extends Animal{
//借用構造函數

constructor(name,age){
  super(name);
  //子類B的構造函數之中的super(),表明調用父類的構造函數。 super雖然表明了父類A的構造函數,可是返回的是子類B的實例,即super內部的this指的是B,所以super()在這裏至關於A.prototype.constructor.call(this)。
  this.age=age;
}
sayAge(){
console.log("my age is",this.age) }}let d = new Dog("多多",2);d.sayName();d.sayAge();~~~~

` |

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息