es6涉及的那點東西


前言

ECMAScript 6(以下簡稱ES6)是JavaScript語言的下一代標准。因為當前版本的ES6是在2015年發布的,所以又稱ECMAScript 2015。 也就是說,ES6就是ES2015。
目前並不是所有瀏覽器都能兼容ES6全部特性,我們可以使用Babel工具來轉換成es5 Babel是一個廣泛使用的ES6轉碼器,可以將ES6代碼轉為ES5代碼

最常用的ES6特性 let, const, class, extends, super, arrow functions, template string, destructuring, default, rest arguments

一、let 、const命令

1、let用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效
2、不存在變量提升,let不像var那樣會發生“變量提升”現象。所以,變量一定要在聲明后使用,否則報錯。

console.log(foo); // 輸出undefined
console.log(bar); // 報錯ReferenceError
var foo =2;let bar =2;

3、在let和const之間,建議優先使用const,尤其是在全局環境,不應該設置變量,只應設置常量。

const聲明常量還有兩個好處,一是閱讀代碼的人立刻會意識到不應該修改這個值,二是防止了無意間修改變量值所導致的錯誤。

4、ES6明確規定,如果區塊中存在let和const命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。 總之,在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。也就是“暫時性死區”。

二、es6模塊(module)

JavaScript一直沒有模塊(module)體系,無法將一個大程序拆分成互相依賴的小文件,再用簡單的方法拼裝起來。其他語言都有這項功能,比如Ruby的require、Python的import,甚至就連CSS都有@import,但是JavaScript任何這方面的支持都沒有,這對開發大型的、復雜的項目形成了巨大障礙。

這有可能導致兩個問題:

  • 一方面js代碼變得很臃腫,難以維護
  • 另一方面我們常常得很注意每個script標簽在html中的位置,因為它們通常有依賴關系,順序錯了可能就會出bug
  • 在es6之前為解決上面提到的問題,我們得利用第三方提供的一些方案,主要有兩種CommonJS(服務器端)和AMD(瀏覽器端,如require.js)。

在ES6之前,社區制定了一些模塊加載方案,最主要的有CommonJS和AMD兩種。前者用於服務器,后者用於瀏覽器。ES6在語言規格的層面上,實現了模塊功能,而且實現得相當簡單,完全可以取代現有的CommonJS和AMD規范,成為瀏覽器和服務器通用的模塊解決方案。

傳統的寫法 首先我們回顧下require.js的寫法。假設我們有兩個js文件: index.js和content.js,現在我們想要在index.js中使用content.js返回的結果,我們要怎么做呢? 首先定義:

//content.js
define('content.js', function(){
    return'A cat';
})

然后require:

//index.js
require(['./content.js'], function(animal){
    console.log(animal);   //A cat
})

CommonJS寫法

//index.js
var animal = require('./content.js')

//content.js
module.exports = 'A cat'

ES6的寫法

//index.js
import animal from'./content'//content.js
export default'A cat'

// ES6模塊

import { stat, exists, readFile } from 'fs';

上面代碼的實質是從fs模塊加載3個方法,其他方法不加載。這種加載稱為“編譯時加載”,即ES6可以在編譯時就完成模塊加載,效率要比CommonJS模塊的加載方式高。當然,這也導致了沒法引用ES6模塊本身,因為它不是對象。

瀏覽器使用ES6模塊的語法如下。

<script type="module" src="foo.js"></script>

上面代碼在網頁中插入一個模塊foo.js,由於type屬性設為module,所以瀏覽器知道這是一個ES6模塊。

Node的默認模塊格式是CommonJS,目前還沒決定怎么支持ES6模塊。所以,只能通過Babel這樣的轉碼器,在Node里面使用ES6模塊。

ES6的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上"use strict";。

1、export命令

模塊功能主要由兩個命令構成:export和import。export命令用於規定模塊的對外接口,import命令用於輸入其他模塊提供的功能。 一個模塊就是一個獨立的文件。該文件內部的所有變量,外部無法獲取。如果你希望外部能夠讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量。例如,

// profile.js
export var firstName ='Michael';
export var lastName ='Jackson';
export var year =1958;

也可以是下面這種寫法(優先考慮使用),

// profile.js
var firstName ='Michael';var lastName ='Jackson';var year =1958;

export {firstName, lastName, year};

export命令除了輸出變量,還可以輸出函數或類(class)。

export function multiply(x, y){return x * y;};

可以使用as關鍵字重命名

function v1(){...}
function v2(){...}

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

注意:export命令可以出現在模塊的任何位置,只要處於模塊頂層就可以。如果處於塊級作用域內,就會報錯,import命令也是如此,這是因為處於條件代碼塊之中,就沒法做靜態優化了,違背了ES6模塊的設計初衷。下面代碼中,export語句放在函數之中,結果報錯。

function foo(){
  export default 'bar' // SyntaxError
}
foo()

2、import命令

使用export命令定義了模塊的對外接口以后,其他JS文件就可以通過import命令加載這個模塊(文件)。

import {firstName, lastName, year} from './profile';

上面代碼的import命令,就用於加載profile.js文件,並從中輸入變量。import命令接受一個對象(用大括號表示),里面指定要從其他模塊導入的變量名

使用as關鍵字將輸入的變量重新命名

import { lastName as surname } from './profile';

import命令具有提升效果,會提升到整個模塊的頭部,首先執行。

foo();

import { foo } from 'my_module';

上面的代碼不會報錯,因為import的執行早於foo的調用。

import語句會執行所加載的模塊,但是不輸入任何值。

import 'lodash';

import 也可以引用文件夾/目錄

如import router from './router' 

這里router是個目錄 里面有個index.js文件

3、模塊整體加載

circle模塊有2個方法

// circle.js

export function area(radius){return Math.PI * radius * radius;}

export function circumference(radius){return2* Math.PI * radius;}

通過使用*號加載整個模塊
import * as circle from './circle';

console.log('圓面積:'+ circle.area(4));
console.log('圓周長:'+ circle.circumference(14));

三、class類

1、class的基本用法 ES6提供了更接近傳統語言的寫法,引入了Class(類)這個概念,作為對象的模板。通過class關鍵字,可以定義類

//定義類
class Point{
  constructor(x, y){
    this.x = x;
    this.y = y;
  }
  toString(){
    return'('+this.x +', '+this.y +')';
  }
}

constructor這就是構造方法,而this關鍵字則代表實例對象 定義“類”的方法的時候,前面不需要加上function這個關鍵字,直接把函數定義放進去了就可以了。另外,方法之間不需要逗號分隔,加了會報錯。

使用時直接對類使用new命令

class Bar{
  doStuff(){
    console.log('stuff');
  }
}

    var b =new Bar();
b.doStuff() // "stuff"

2、constructor構造方法

constructor方法是類的默認方法,通過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被默認添加。 constructor()

3、class表達式

與函數一樣,類也可以使用表達式的形式定義。

const MyClass = class Me{
  getClassName(){
    return Me.name;
  }
};

這個類的名字是MyClass而不是Me,Me只在Class的內部代碼可用,指代當前類。

如果類的內部沒用到的話,可以省略Me

const MyClass = class {/* ... */};

采用Class表達式,可以寫出立即執行的Class。

let person =newclass{
  constructor(name){
    this.name = name;
  }
  sayName(){
    console.log(this.name);
  }
}('張三');

person.sayName(); // "張三"

4、class類繼承

通過extends關鍵字實現繼承

class ColorPoint extends Point{}

四、arrow function箭頭函數

function(i){ 
  return i + 1; 
} //ES5
(i) => i + 1//ES6

如果方程比較復雜,則需要用把代碼包起來:

function(x, y){ 
    x++;
    y--;
    return x + y;
}
(x, y) => {
  x++; y--; 
  return x+y
}

在對象方法中使用this

傳統的寫法需要將this傳給self,再用self來指代this

 says(say){
       var self = this;
       setTimeout(function(){
           console.log(self.type + ' says ' + say)
       }, 1000)

使用es6的寫法

classAnimal {
    constructor(){
        this.type = 'animal'
    }
    says(say){
        setTimeout( () => {
            console.log(this.type + ' says ' + say)
        }, 1000)
    }
}
 var animal = new Animal()
 animal.says('hi')  //animal says hi

當我們使用箭頭函數時,函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。並不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,它的this是繼承外面的,因此內部的this就是外層代碼塊的this。

五、template string

當我們要插入大段的html內容到文檔中時,傳統的寫法非常麻煩,所以之前我們通常會引用一些模板工具庫,比如mustache等等

$("#result").append(
  "There are <b>" + basket.count + "</b> " +
  "items in your basket, " +
  "<em>" + basket.onSale +
  "</em> are on sale!"
);

我們要用一堆的'+'號來連接文本與變量,而使用ES6的新特性模板字符串``后

$("#result").append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

用反引號(\)來標識起始,用$`來引用變量,而且所有的空格和縮進都會被保留在輸出之中

六、default, rest

default很簡單,意思就是默認值,調用animal()方法時忘了傳參數,傳統的做法就是加上這一句type = type || 'cat' 來指定默認值

function animal(type){
    type = type || 'cat'  
    console.log(type)
}
animal()

用ES6我們而已直接這么寫:

function animal(type = 'cat'){
    console.log(type)
}
animal()

rest語法也很簡單,看例子:

function animals(...types){
    console.log(types)
}
animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]

參考閱讀

https://segmentfault.com/a/1190000004365693#articleHeader7
http://es6.ruanyifeng.com/


免責聲明!

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



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