ES6模塊化與經常使用功能

目前開發環境已經普及使用,如vue,react等,但瀏覽器環境卻支持很差,因此須要開發環境編譯,下面介紹下開發環境的使用和經常使用語法:html

一,ES6模塊化
1,模塊化的基本語法

ES6 的模塊自動採用嚴格模式,無論你有沒有在模塊頭部加上"use strict";vue

模塊功能主要由兩個命令構成:exportimport(注意有無default)export命令用於規定模塊的對外接口,import命令用於輸入其餘模塊提供的功能。java

 
2,開發環境配置(babel編譯ES6語法,模塊化可用webpack和rollup)
(1)開發環境 babel-語法層面(編譯) https://babeljs.cn/ (淘寶npm鏡像  http://npm.taobao.org/
電腦有node環境,運行npm init(建立package.json文件)----輸入相關信息,默認便可,不要和工具名同樣就行
npm init
使用淘寶npm鏡像更快地安裝babel依賴:
npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest --registry=https://registry.npm.taobao.org 
建立  .babelrc 文件
{
    "presets": ["es2015","latest"],
}
全局安裝babel-cli:
 npm install -g babel-cli
檢驗版本是否安裝成功:
babel --version
建立./src/index.js
輸入內容:
[1,2,3].map(item => item + 1);
運行:
babel ./src/index.js,
編譯結果以下:
[1, 2, 3].map(function (item) {
  return item + 1;
});

 

(2)開發環境 webpack(現代 JavaScript 應用程序的 靜態模塊打包器(module bundler)),功能強大
安裝webpack和babel編譯:
npm install webpack babel-loader --save-dev --registry=https://registry.npm.taobao.org
配置webpack.config.js
// var path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname,
    filename: './build/bundle.js'
  },
  module:{
      rules:[{
          test:/\.js?$/,
          exclude:/(node_modules)/,
          loader:'babel-loader'
      }]
  }
};
配置 package.json中的scripts
{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-polyfill": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-latest": "^6.24.1",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14"
  }
}
運行
npm start
 
 
(3)開發環境-rollup,只將須要的代碼提取出來打包,能大大減少代碼體積
npm init 建立一個package.json。
npm init
安裝
npm i rollup rollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest --save-dev
配置.babelrc
{
    "presets": [
        ["latest",
            {
                "es2015":
                {
                    "modules": false
                }
            }

        ]
    ],
    "plugins": ["external-helpers"]
}
配置 rollup-config.js
import babel from 'rollup-plugin-babel'
import resolve from 'rollup-plugin-node-resolve'

export default {
  input: 'src/index.js',
  output: {
    file: 'build/bundle.js',
    format: 'umd' //通用模塊定義,兼容AMD,CommonJS和通常的全局定義
  },
  plugins:[
        resolve(),
        babel({
            exclude:'node_modules/**'
        })
    ],
};

 修改package.json的scriptsnode

{
  "name": "rollup-xiaosili",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "rollup -c rollup.config.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-preset-latest": "^6.24.1",
    "rollup": "^0.57.1",
    "rollup-plugin-babel": "^3.0.3",
    "rollup-plugin-node-resolve": "^3.3.0"
  }
}

 新建相關文件,輸入內容react

運行
npm start

 

3,關於JS衆多模塊化標準
歷史上,JavaScript 一直沒有模塊(module)體系,沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。其餘語言都有這項功能,好比 Ruby 的 require、Python 的 import,甚至就連 CSS 都有 @import,可是 JavaScript 任何這方面的支持都沒有,這對開發大型的、複雜的項目造成了巨大障礙。

在 ES6 以前,社區制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種。前者用於服務器,後者用於瀏覽器。ES6 在語言標準的層面上,實現了模塊功能,並且實現得至關簡單,徹底能夠取代 CommonJS 和 AMD 規範,成爲瀏覽器和服務器通用的模塊解決方案。(現狀是,nodejs積極支持,瀏覽器還沒有統一)webpack

 ES6 模塊的設計思想是儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時肯定這些東西。好比,CommonJS 模塊就是對象,輸入時必須查找對象屬性。es6

 
二,Class和普通構造函數有何區別
1,js構造函數
function MathHandle(x, y) {
    this.x = x;
    this.y = y;
}

MathHandle.prototype.add = function() {
    return this.x + this.y;
};

var m = new MathHandle(1, 2);
console.log(m.add()); //3
2,Class基本語法
class MathHandle1 {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    add() {
        return this.x + this.y;
    }
}
var m1 = new MathHandle1(1,2);
console.log(m1.add()); //3
console.log(typeof MathHandle1);  //function
console.log(MathHandle1 === MathHandle1.prototype.constructor); //true
console.log(m1.__proto__ === MathHandle1.prototype); //true
3,兩者區別
 
(1) class在語法上更加貼合面向對象的寫法
(2) class實現繼承更易讀,易理解
(3) 更易於寫java等後端語言的使用
(4) 本質是語法糖,仍是使用prototype繼承方式
附:class繼承實現
 
三,Promise的基本語法

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

所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理。npm

Promise對象有如下兩個特色。編程

(1)對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是「承諾」,表示其餘手段沒法改變。

(2)一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱爲 resolved(已定型)。若是改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。

注意,爲了行文方便,本章後面的resolved統一隻指fulfilled狀態,不包含rejected狀態。

先看js的一個例子:

function loadImg(src, callback, fail) {
    var img = document.createElement('img');
    img.onload = function() {
        callback(img);
    }
    img.onerror = function() {
        fail();
    }
    img.src = src;
}

var src = "https://shared-https.ydstatic.com/dict/v2016/result/logo.png";
loadImg(src, function(img) { //加載圖片,異步請求
    console.log(img.width); //164
}, function() {
    console.log('failed');
})
使用Promise:

ES6 規定,Promise對象是一個構造函數,用來生成Promise實例。

Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolvereject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。

resolve函數的做用是,將Promise對象的狀態從「未完成」變爲「成功」(即從 pending 變爲 resolved),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去;reject函數的做用是,將Promise對象的狀態從「未完成」變爲「失敗」(即從 pending 變爲 rejected),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。

例:

   function loadImg(src) {
        const promise = new Promise(function(resolve, reject) { //new Promise實例
            var img = document.createElement('img');
            img.src = src;
            img.onload = function() {
                resolve(img);
            }
            img.onerror = function() {
                reject('圖片加載失敗');
            }
        });
        return promise; //返回 Promise實例
    }
    var src = "https://shared-https.ydstatic.com/dict/v2016/result/logo.png";
    var result = loadImg(src); //Promise實例
    result.then(function(img) { //then監聽結果,成功時執行resolve(), 失敗時執行reject()
        console.log(1, img.width); //1 164
        return img;
    }, function(img) {
        console.log('failed');
        return img;
    }).then(function(img) {
        console.log(2, img.height) //2 36
    })
四,ES6其餘經常使用的功能(簡單經常使用的)
1,let/const(let定義變量,不存在變量提高,const定義常量)
let i = 10;
i = 100;
const j = 20;
j = 200;

 編譯以下:

SyntaxError: ./src/index1.js: "j" is read-only
  2 | i = 100;
  3 | const j = 20;
> 4 | j = 200;

 

2,多行字符串/模版變量
const name = 'zs',age = 20;
const html = `<div><p>${name}</p><p>${age}</p></div>`; //注意這裏是反引號

 編譯以下:

var name = 'zs',
    age = 20;
var html = '<div><p>' + name + '</p><p>' + age + '</p></div>'; //注意這裏是反引號

 

 
3,解構賦值
const arr = ['xxx','yyy','zzz','hhh'];
const [x,y,z] = arr;

const obj = {a:1,b:2,c:3};
const {a,c} = obj;
編譯以下:
var arr = ['xxx', 'yyy', 'zzz', 'hhh'];
var x = arr[0],
    y = arr[1],
    z = arr[2];


var obj = { a: 1, b: 2, c: 3 };
var a = obj.a,
    c = obj.c;
4,塊級做用域
const obj = {a:10,b:20};
for(let item in obj) {
    console.log(item);
}
console.log(item);//報錯 item is not defined

 編譯以下:

var obj = { a: 10, b: 20 };
for (var _item in obj) {
    console.log(_item);
}
console.log(item); //報錯 item is not defined

 

5,函數默認參數
function fn(a,b=0) {

}

 編譯以下:

function fn(a) {
    var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
}

 

6,箭頭函數
var arr = [1, 2, 3];
arr.map((item, index) => {
    return item + index;
})

 編譯以下:

var arr = [1, 2, 3];
arr.map(function (item, index) {
  return item + index;
});

箭頭函數中的this:this 實際上是包含該箭頭函數最近的一個 function 上下文中的 this(若是沒有最近的 function,就是全局)

function fn() {
    console.log('real',this);//this === {a:100}
    var arr = [1,2,3];
    
    // 普通JS
    arr.map(function(item) {
        console.log('js',this);//this === window
        return item + 1;
    })

    // 箭頭函數
    arr.map(item => {
        console.log('es6',this);//this === {a:100}
        return item + 1;
    })
}
fn.call({a:100});
編譯以下:
function fn() {
    var _this = this;

    console.log('real', this); //this === {a:100}
    var arr = [1, 2, 3];

    // 普通JS
    arr.map(function (item) {
        console.log('js', this); //this === window
        return item + 1;
    });

    // 箭頭函數
    arr.map(function (item) {
        console.log('es6', _this); //this === {a:100}
        return item + 1;
    });
}
fn.call({ a: 100 });

 

相關文章
相關標籤/搜索