摘自(ES6標準入門)(第3版)(阮一峯著)經典案例---持續更新中

1.模擬next方法返回值的例子

function makeIterator(array){
   var nextIndex = 0;
   return {
     next: function(){
       return nextIndex < array.length ? {value: array[nextIndex++],done:false} : {value: undefined, done: true};
     }
   }
}
var it = makeIterator(['a','b']);
it.next(); // {value: "a", done: false}
it.next(); // {value: "b", done: true}
it.next(); // {value: undefined, done: true}

2.用Promise對象實現AJAX操做

// 建立getJSON方法
var getJSON = function (url) {
  var promise = new Promise(function(resolve,reject){
     var client = new XMLHttpRequest() || new ActiveXObject('Microsoft.XMLHTTP');
     client.open('GET',url);
     client.onreadystatechange = handler;
     client.responseType = 'json';
     client.setRequestHeader('Accept','application/json');
     client.send();
     
     function handler() {
       if(this.readyState===4) {
          if(this.status ===200) {
            resolve(this.response);  
          }else {
            reject(new Error(this.statusText));
          }
       }
     }
  })
  return promise;
}
// 調用方法
getJSON('https://www.qinghuo.ltd:8888').then(function(json){
  console.log('後臺返回數據'+json);
},function(err){
  console.log('訪問出錯'+err);
})

3.變量的解構賦值的用途

  • 交換變量的值

let x = 1;
let y = 2;
[x,y] = [y,x];
//上面的代碼交換變量x和y的值,這樣的寫法不只簡潔,並且易讀,語義很是清晰.
  • 從函數返回多個值

// 返回一個數組
function example() {
  return [1,2,3];
}
let [a,b,c] = example();
// 返回一個對象
function example() {
   return {
     foo: 1,
     bar: 2
   }
}
let {foo,bar} = example();
  • 函數參數的定義

// 解構賦值能夠方便的將一組參數和變量名對應起來
// 參數是一組有次序的值
function f([x,y,z]) {...}
f([1,2,3]);
// 參數是一組無次序的值
function f({x,y,z}) {...}
f({z:3,y:2,x:1});
  • 提取JSON數據

// 解構賦值對提取JSON對象中的數據尤爲有用
let jsonData = {
  id: 42,
  status: "OK",
  data: [876, 534]
};
let {id,status,data:number} = jsonData;
console.log(id,status,number);
// 42,"OK",[876, 534]
  • 函數參數的默認值

JQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  catch = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};
// 指定參數的默認值,這樣就避免了在函數體內部再寫 var foo = config.foo || 'default foo';這樣的語句.
  • 遍歷Map結構

// 任何部署了iterator接口的對象均可以用for...of循環遍歷.Map結構原生支持Iterator接口,配合變量的解構賦值獲取鍵名和鍵值就很是方便.
var map = new Map();
map.set('first','hello');
map.set('second','world');

for(let [key,value] of map) {
  console.log(key + 'is' + value);
}
// first is hello
// second is world

// 若是隻想獲取鍵名,或者只想獲取鍵值,能夠寫成下面這樣
// 獲取鍵名
for(let [key] of map) {...}
// 獲取鍵值
for(let [,value] of map) {...}
  • 輸入模塊的指定方法

// 加載模塊時,每每須要指定輸入的方法.解構賦值使輸入語句很是清晰
const {SourceMapConsumer, SourceNode} = require("source-map");

4.肯定一個字符串是否包含在另外一個字符串中的四種方法

  1. indexOf() : 返回Number,表示該值在字符串中的索引,未找到,則返回-1

  2. includes() : 返回布爾值,表示是否找到參數字符串

  3. startsWith() : 返回布爾值,表示參數字符串是否在源字符串的頭部

  4. endsWith() : 返回布爾值,表示參數字符串是否在源字符串的尾部

// 案例:
var s = 'hello world!';
console.log(s.indexOf('e')) // 1
console.log(s.includes('e')) // true
console.log(s.startsWith('h')) // true
console.log(s.endsWith('!')) // true

5.尾遞歸

遞歸很是消耗內存,由於須要同時保存成百上千的調用幀,很容易發生"棧溢出"錯誤(stack overflow).但對於尾遞歸來講,因爲只存在一個調用幀,因此永遠不會發生"棧溢出"錯誤
// 正常遞歸調用,求階乘
function factorial(n) {
  if(n===1) {
    return 1;
  }else {
    return n*factorial(n-1);
  }
}
factorial(5) // 120
// 尾遞歸調用
function factorial(n,total) {
  if(n===1) {
    return total;
  }else {
    return factorial(n-1,n*total);
  }
}
factorial(5,1) // 120
//上面的代碼是一個階乘函數,計算n的階乘,最多須要保存n個調用記錄,複雜度爲O(n).若是改爲成爲尾遞歸,值保留一個調用記錄,則複雜度爲O(1).

//正常的斐波那契數列
function Fibonacci (n) {
  if(n<=2) {
    return 1;
  }else {
    return Fibonacci (n-1) + Fibonacci (n-2);
  }
}
Fibonacci (10) // 89
Fibonacci (100) // 堆棧溢出
Fibonacci (500) // 堆棧溢出
// 尾遞歸優化的斐波那契數列
function Fibonacci2 (n, ac1 = 0, ac2 = 1) {
  if(n<=1) {
    return ac2;
  }else {
    return Fibonacci2 (n-1, ac2, ac1+ ac2)
  }
}
Fibonacci2 (100) // 5731478440138430000
Fibonacci2 (1000) // 7.022033e+208
Fibonacci2 (10000) // Infinity

6.屬性的遍歷

  • for in

for...in循環遍歷對象自身和繼承的可枚舉屬性(不包含Symbol屬性)
  • Object.keys(obj)

Object.keys返回一個數組,包括對象自身的(不包含繼承的)全部的可枚舉屬性(不包括Symbol屬性)
  • Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一個數組,包含對象自身的全部屬性(不包含Symbol屬性,但包含不可枚舉屬性)
  • Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一個數組,包含對象自身的全部Symbol屬性
  • Reflect.ownKeys(obj)

Reflect.ownKeys返回一個數組,包含對象自身的全部屬性,無論屬性名是Symbol仍是字符串,也無論是否可枚舉.

以上5種方法遍歷對象屬性時都遵照一樣的屬性遍歷次序規則ajax

  • 首先遍歷全部屬性名爲數值的屬性,按照數字排序.
  • 其次遍歷全部屬性名爲字符串的屬性,按照生成時間排序.
  • 最後遍歷全部屬性名爲Symbol值得屬性,按照生成時間排序.
舉例:Reflect.ownKeys({[Symbol()]:0,b:0,10:0,2:0,a:0})
// ['2','10','b','a',Symbol()]

7.Iterator的做用

Iterator的做用有3個:一是爲各類數據結構提供一個統一的,簡便的訪問接口;
二是使得數據結構的成員可以按照某種次序排列;
三是ES6創造了一種新的遍歷命令--for of循環,Iterator接口主要供for of消費

8.Iterator的遍歷過程

1.建立一個指針對象,指向當前數據結構的起始位置.也就是說,遍歷器對象本質上就是一個指針對象.
2.第一次調用指針對象的next方法,能夠將指針指向數據結構的第一個成員.
3.第二次調用指針對象的next方法,指針指向數據結構的第二個成員.
4.不斷調用指針對象的next方法,直到它指向數據結構的結束位置.

9.異步編程的5種方法

  • 回調函數
  • 事件監聽
  • 發佈/訂閱
  • Promise對象
  • Generator函數

圖片描述

相關文章
相關標籤/搜索