1. 程式人生 > >es6 學習筆記(一)

es6 學習筆記(一)

句法 value creat dirname index 每次 並且 ron ner

環境搭建和簡單實踐

怎麽es6還要環境搭建呢?我用的還是javascript嗎?然而不是這麽一回事。
es6在語法上有很多的變化,算是脫胎換骨了,但是因為瀏覽器還沒有完全支持es6的新語法,所以使用es6開發,就應該先將其轉化為es5,那麽就需要工具來完成,

babel

Babel是一個編譯器,負責將源代碼轉換成指定的語法的目標代碼,可以使之很好的在運行環境中執行我們的代碼。
安裝babel的命令行工具:

//一般要先在當前項目生成一個package.json;然後將babel-cli安裝在本地 ,它只是一個開發依賴。另外不同的項目依賴庫的版本可能都不同,全局的babel-cli庫也不能保證兼容各個項目中其他依賴庫的版本。

$ npm install -D babel-cli;

安裝轉碼規則包,Babel支持很多語法的轉碼,可以選擇集成的。

babel-preset-env 是一個新的 preset,可以根據配置的目標運行環境(environment)自動啟用需要的 babel 插件,babel-preset-env 的工作方式類似 babel-preset-latest,唯一不同的就是 babel-preset-env 會根據配置的 env 只編譯那些還不支持的特性。

$ npm install -D babel-preset-env

然後編譯,

//編譯某個具體的js文件
$ babel index.js --out-file index-compile.js
//編譯目錄中所有的js文件並另存到指定目錄
$ babel src --out-dir lib / $ babel src -d lib

每次都這樣做,太繁瑣了?試用一下這條命令。在package.json文件中的script中添加:

"build": "babel src -d lib"

它可以實現簡單的編譯的功能,不過這不是最好的解決方案,

因為Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API ,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(比如 Object.assign)都不會轉碼

為了能夠完全轉換es6的內容,需要安裝babel-polyfill插件

1.先引入webpack,這裏只是因為babel-polyfill可以在Node/Browserify/webpack中使用

//全局安裝,在配置完成後,可以直接通過webpack運行,
$ npm install -g webpack
//一般會裝在本地項目中,就不能直接使用webpack需要找node_module中的webpack的位置。
$ npm install -D webpack

2.安裝babel-polyfill插件,babel-cli,babel-preset-env

$ npm install -save-dev babel-polyfill babel-cli babel-preset-env

3.在需要的文件中引入babel-polyfill:

import "babel-polyfill";
//node.js中引入:require(‘babel-polyfill‘);


4.配置webpack.config.js文件,將[‘babel-polyfill‘, ‘./src/index.js‘] 寫到entry屬性中。如下

const path = require(‘path‘);

module.exports = {
  entry: [‘babel-polyfill‘, ‘./src/index.js‘],
  module: {
    rules: [
      { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
    ]
  },
  output: {
    filename: ‘bundle.js‘,
    path: path.resolve(__dirname, ‘dist‘)
  }
};

  

5.配置.babelrc文件

{
    "persets": ["env"];
}

  

6.啟動webpack


$ webpack

promise

promise是什麽?(來自sf.gg的promise百科)

Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了 Promise 對象。

所謂 Promise,簡單說就是一個容器,裏面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。

promise方法:

1.構造函數

Promise(
    function(resolve, reject) {
    }
);

  

2.實例,構造函數用於生成Promise對象

let promise = new Promise(function(resolve, reject) { });

3.then方法

let promise = function() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {resolve()})
  })
}

promise()
.then(function() {
  //成功的事
  return new Promise(function(resolve, reject) {
    //異步請求
    setTimeout(function() {reslove()})
  })
})
.catch(() => {
  //錯誤處理
})
.then(function() {
  //成功的事
  return new Promise(function(resolve, reject) {
    //異步請求
    setTimeout(function() {reslove()})
  })
})
.catch(() => {
  //錯誤處理
})
.then(function() {

})

  

Promise鏈式調用的原因?

因為Promise.prototype.then方法和Promise.prototype.catch方法都返回Promise對象。所以可以鏈式調用

Promise對象的其他用法。

1.Promise.all()
將多個Promise實例,包裝成一個新的Promise實例

let promise = Promise.all([promiseOne,promiseTwo]);

而且,只有當promiseOne 和 promiseTwo 都成功的時候,promise才會成功

2.Promise.race()

該方法同樣是將多個Promise實例,包裝成一個新的Promise實例。只不過在這種情況下,只要其中一個被成功調用,promise 就會被成功調用。

繼續研究參考:https://segmentfault.com/a/1190000011742644

axios

基於http客戶端的promise,面向瀏覽器和nodejs

安裝:
使用 npm:

$ npm install axios

使用 bower:

$ bower install axios

引入axios.js

在bowe_components中引入axios.js

axios請求

axios.get(‘http://h6.duchengjiu.top/shop/api_goods.php‘)
    .then(response => {
    console.log(response.data);
});

  

generator & yield

1.生成器函數(Generator Function)

//聲明式
function* gene() {
    //...
}




//定義式
const gene = function*() {
    //...
}


2.yield

yield的作用與return相似,但是yield不會退出函數體,而是切出當前函數的運行時(此處為一個類協程,Semi-coroutine),並與此同時可以講一個值(可以是任何類型)帶到主線程中。

繼續理解:生成器(Generator)

3.使用方法:
構建生成器函數

function* genFn() {
    let a = 2
    yield a
    while (true) {
        yield a = a / (2 * a + 1)
    }
}

執行generator函數

generator函數不能直接作為函數來使用,執行generator函數會返回一個生成器對象,將用於運行生成器內容和接受其中的值。

const gen = genFn()

運行生成器內容

for (const a of gen) {
    if (a < 1/100) break
    console.log(a)
}


叠代器

1.for-in
都知道for-in循環用來遍歷對象,但是細心的你也會發現,for-in無法控制遍歷的順序,它永遠都是從第一個到最後一個。

2.for-of
for-of是es6的新語法,它用來配合叠代器,叠代對象,我們可以控制叠代順序,

3.Symbol.iterator
對象被叠代的條件是它需要有一個Symbol.iterator屬性,他是一個獨一無二的屬性,暫不詳細介紹。

4.叠代器長啥樣?

iterator[Symbol.iterator] = function () {
    return {
    next: function () {}
    }
}

//iterator[Symbol.iterator]() 它會返回一個類似於{next: function() {}}對象,原型是Array Iterator

let iterator = iterator[Symbol.iterator]();

//iterator.next(),會返回一個類似於{value: …, done: [true/false]}的對象,

iterator.next();

  

那麽next()內部大概是這樣的:

table[Symbol.iterator] = function () {
    var keys = Object.keys(this).sort();
    var index = 0;
    return {
        next: function () {
            return {
                value: keys[index], done: index++ >= keys.length
            };
        }
    }
}

  

針對對象,自己寫一個叠代器

{
    let obj={
    start:[1,3,2],
    end:[7,9,8],
    [Symbol.iterator](){
        let self=this;
        let index=0;
        let arr=self.start.concat(self.end);
        let len=arr.length;
        return {
            next(){
                if(index<len){
                    return {
                        value:arr[index++],
                        done:false
                    }
                } else {
                    return {
                        value:arr[index++],
                        done:true
                    }
                }
            }
        }
    }
    // 遍歷叠代器
    let iterator = obj[Symbol.iterator]();
    console.log(iterator);
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
}         

5.惰性執行:

如果next()函數永遠不被調用的話,我們就浪費了性能。所以讓我們來優化它:

table[Symbol.iterator] = function () {
  var _this = this;
  var keys = null;
  var index = 0;

  return {
    next: function () {
      if (keys === null) {
        keys = Object.keys(_this).sort();
      }

      return {
        value: keys[index], done: index++ >= keys.length
      };
    }
  }
}

6.內置叠代器

String,Array,TypedArray,Map和Set都是內置叠代器,因為它們的原型中都有一個Symbol.iterator方法

7.Generator函數

function* iterator(arr) {
    for(let item of arr) {
        yield item;
    }
}
let iter = iterator([1,2,3,5,6,7]);
for(let k of iter) {
    console.log(k);
}

這兩種都可以用來叠代,iter是一個叠代器,像上面我們分析的那樣,
它內部會返回 {next: function() { } }, for-of也是同樣。

//iter.next();
//for(let k of iter) {}

8.iterables

iterable是一個概念,表示有Symbol.iterator屬性的object,
這個屬性指向一個generator函數,調用這個函數,會返回一個關於這個對象的iterator,
在ES6中所有的集合類對象(array, set, maps)和字符串都是iterable,並且有自己默認的iterator,
所以在使用for-of叠代的時候,每次都是利用了對象上的iterator,調用next(),

9.向叠代器中傳遞參數

function* createIterator() {
    let first = yield 1;
    let second = yield first + 2;
    yield second + 3;
}

let i= createItreator()

i.next() // {value:1 done: false}
i.next(5) // {value: 7 done: false}
i.next(3) // {value: 6 done: false}e}

10.應用實例

function run(taskDef) {
    let task = taskDef();
    let value = task.next()

    function step() {
        if (!value.done) {
            value = task.next(value.value)
            step()
        }
    }
    step()
}

run(function*(){
    let first = yield 1;
    let second = yield first + 3;
    yield second + 4;
})

11.應用實例2

es6 學習筆記(一)