es6基本介紹及使用


1.什么是es6

ECMAScript 6.0(以下簡稱ES6)是JavaScript語言的下一代標准,已經在2015年6月正式發布了。它的目標,是使得JavaScript語言可以用來編寫復雜的大型應用程序,成為企業級開發語言。

ECMAScript和JavaScript的關系是,前者是后者的規格,后者是前者的一種實現。

es6入門文檔:http://caibaojian.com/es6/

2.node中使用es6

Babel是一個廣泛使用的ES6轉碼器,可以將ES6代碼轉為ES5代碼,從而在現有環境執行。

2.1配置文件 .babelrc

Babel的配置文件是.babelrc,存放在項目的根目錄下。使用Babel的第一步,就是配置這個文件。該文件用來設置轉碼規則和插件,基本格式如下:

{
  "presets": [],
  "plugins": []
}

2.2安裝es6轉換模塊

presets字段設定轉碼規則,官方提供以下的規則集,你可以根據需要安裝。

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

// react轉碼規則
$ npm install --save-dev babel-preset-react

// ES7不同階段語法提案的轉碼規則(共有4個階段),選裝一個
$ npm install --save-dev babel-preset-stage-0
$ npm install --save-dev babel-preset-stage-1
$ npm install --save-dev babel-preset-stage-2
$ npm install --save-dev babel-preset-stage-3

然后,將這些規則加入.babelrc

{
    "presets": [
      "es2015",
      "react",
      "stage-2"
    ],
    "plugins": []
}

注意,Babel工具和模塊的使用,都必須先寫好.babelrc

2.3全局安裝命令行工具

Babel提供babel-cli工具,用於命令行轉碼。

cnpm install babel‐cli ‐g

2.4使用

babel-node js文件名

3.語法新特性

3.1 變量聲明let

在es6之前,var關鍵字聲明變量。無論聲明在何處,都會被視為聲明在函數的最頂部,這是函數變量的提升。如下:

function aa() {
    if(bool) {
        //聲明變量
        var test = 'hello man'
    } else {
        console.log(test)
    }
}

上面代碼實際是:

function aa() {
    var test // 變量提升
    if(bool) {
        test = 'hello man'
    } else {
        //此處訪問test 值為undefined
        console.log(test)
    }
    //此處訪問test 值為undefined
}

es6后,通常用let和const來聲明,let表示變量、const表示常量。let和const都是塊級作用域(在一個函數內部 ,在一個代碼塊內部)。如下:

//變量聲明let
function test(b){
    if(b){
        //var 全局變量; let 局部變量
        let a = 'abc';
    }
    //a 在此處訪問不到
    console.log(a);
} 
test(true);

終端運行:node demo1,會報錯:ReferenceError: a is not defined

3.2 常量聲明

const用於常量聲明:

//常量聲明,常量不能進行改變
const name = 'abc';
// name = "xyz";	//再次賦值會報錯
console.log(name);

3.3 模板字符串

反引號(``),是es6模板字符串

1.字符串格式化

將表達式嵌入字符串中進行拼接。用${}來界定。

//1.字符串拼接
//ES5
var name = 'abc';
console.log("你好,"+name+"歡迎來到十次方世界");

//ES6  模板字符串
let name2 = 'xyz';
//反引號`是esc鍵下面的英文符 ${}界定
console.log(`你好,${name2}歡迎來到十次方世界`);

2.換行

//2.換行
//ES5
var info = "Hi \
    man!"

//ES6
var info = `<div>
        <span>hello world</span>
    </div>`

3.4 函數默認參數

es6為函數參數提供了默認值。在定義函數時便初始化函數參數,以便在參數沒有被傳遞前去使用。

//函數默認參數
function test(num = 200){
    console.log(num);
}

test();
test(500);

3.5 箭頭函數

就是函數的快捷寫法。最直觀的三個特點:

1.不需要function關鍵字來創建函數
2.省略return關鍵字
3.繼承當前上下文的 this 關鍵字

//ES5
var add = function(a,b){
    return a+b;
}

//ES6
var add2 = (a,b) => {
    return a+b;
}
//當函數體中只有return語句時,可簡寫成下面
var add3 = (a,b) => a+b;

console.log(add(100,200));
console.log(add2(100,200));
console.log(add3(100,200));

3.6 對象初始化簡寫

ES6允許在對象之中,直接寫變量。這時,屬性名為變量名, 屬性值為變量的值。

function f(x, y) {
  return {x, y};
}

// 等同於
function f(x, y) {
  return {x: x, y: y};
}

f(1, 2) // Object {x: 1, y: 2}

//JSON.stringify()把jsonObject轉化為jsonString
console.log(JSON.stringify(people("abc",12)));

除了屬性簡寫,方法也可以簡寫。

var birth = '2000/01/01';

var Person = {
  name: '張三',

  //等同於birth: birth
  birth,

  // 等同於hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};

3.7 變量的解構賦值

ES6允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。本質上,這種寫法屬於“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。

1.數組的解構賦值

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

//解構不成功,變量的值都會等於`undefined`
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

//不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

//默認值
var [foo = true] = [];
foo // true

[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'

2.對象的解構賦值

對象的解構與數組有一個重要的不同。數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

//1.屬性名與變量名一致
var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

//2.屬性名與變量名不一致
var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

對象的解構賦值的內部機制,是先找到同名屬性,然后再賦給對應的變量。真正被賦值的是后者,而不是前者。

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

foo是匹配的模式,baz才是變量。真正被賦值的是變量baz,而不是模式foo。注意,采用這種寫法時,變量的聲明和賦值是一體的。對於letconst來說,變量不能重新聲明,所以一旦賦值的變量以前聲明過,就會報錯。

let foo;
({foo} = {foo: 1}); // 成功

let baz;
({bar: baz} = {bar: 1}); // 成功

let命令下面一行的圓括號是必須的,否則會報錯。因為解析器會將起首的大括號,理解成一個代碼塊,而不是賦值語句。

解構也可以用於嵌套結構的對象:

var obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"

注意,這時p是模式,不是變量,因此不會被賦值。

3.8 Spread Operator

擴展運算符(...組裝對象或數組。

//組裝數組
const color = ['red','green']
const colorful = [...color,'pink']
console.log(colorful)	//[ 'red', 'green', 'pink' ]

//組裝對象
const people = {name: 'xyz', address: 'aaaaa'}
const peopleful = {...people, age: 18}
console.log( JSON.stringify(peopleful))//{"name":"xyz","address":"aaaaa","age":18}

3.9 import和export

import導入模塊、export導出模塊。

創建lib.js

let fn0 = function(){
    console.log('fno...')
}

export {fn0}

創建demo9.js

import {fn0} from './lib'

fn0()

注意:node(v8.x)本身並不支持import關鍵字,所以我們需要使用babel的命令行工具來執行

babel-node demo9

3.10 Promise對象

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

Promise對象有以下兩個特點:

1.對象的狀態不受外界影響。Promise對象代表一個異步操作,有三種狀態:Pending(進行中)、Resolved(已完成,又稱Fulfilled)和Rejected(已失敗)。

2.一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能:從Pending變為Resolved和從Pending變為Rejected

基本用法:

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

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise構造函數接受一個函數作為參數,該函數的兩個參數分別是resolvereject。它們是兩個函數,由JavaScript引擎提供,不用自己部署。

Promise實例生成以后,可以用then方法分別指定Resolved狀態和Reject狀態的回調函數。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

Promise新建后就會立即執行。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('Resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// Resolved

Promise新建后立即執行,所以首先輸出的是“Promise”。然后,then方法指定的回調函數,將在當前腳本所有同步任務執行完才會執行,所以“Resolved”最后輸出。

下面是一個用Promise對象實現的Ajax操作的例子:

var getJSON = function(url) {
  var promise = new Promise(function(resolve, reject){
    var client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    function handler() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
  });

  return promise;
};

getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出錯了', error);
});

getJSON是對XMLHttpRequest對象的封裝,用於發出一個針對JSON數據的HTTP請求,並且返回一個Promise對象。需要注意的是,在getJSON內部,resolve函數和reject函數調用時,都帶有參數。

如果調用resolve函數和reject函數時帶有參數,那么它們的參數會被傳遞給回調函數。reject函數的參數通常是Error對象的實例,表示拋出的錯誤;resolve函數的參數除了正常的值以外,還可能是另一個Promise實例,表示異步操作的結果有可能是一個值,也有可能是另一個異步操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM