摧枯拉朽,說說ES6的三把火

我是 Jser 我驕傲

JavaScript 現在可謂是屌絲逆襲高富帥的代名詞哈,從當初鬧着玩似的誕生到如今 Github 上力壓羣雄的人氣王,JS 搭着互聯網的順風車一路高歌,自己也從一個爺爺不疼奶奶不愛的殺馬特小腳本蛻變爲一門高大上的主流編程語言。運氣當然重要,ES6 也讓你們看到了這門語言自身的努力和上進,相信 JavaScript 定大有可爲。前端

ES6 發佈於 2015 年 6 月,所以也叫 ES2015,距今已有兩年多。2015 年是銘心刻骨的一年,這一年,股市崩盤,千古跌停,手裏的兩個票更是捱了腰斬,寶寶內心苦。同是這一年,ES6 標準落地,做爲一名前端開發,寶寶內心樂開了花。es6

ES6 的新語法不少很碎,若是想系統地學習一遍,強烈推薦阮一峯老師的 ECMAScript 6 入門。本文的目的不是要介紹 ES6 的新語法,而是想談談 ES6 爲JavaScript 這門語言帶來了什麼,這也是在咱看來 ES6 最重要最激動人心的特性。編程

做用域

做用域一直是程序設計語言的基礎設施。JavaScript 也有做用域,但它的做用域有點怪,稍不留神就會掉到坑裏。瀏覽器

JavaScript 的做用域(scope)有三種類型,分別是 Local,Closure,Global,對應的就是三種做用域變量類型,分別是局部變量,閉包變量和全局變量。閉包

好比下面一段代碼:編程語言

var a = 'global'
function outer(){
    var b = 'closure'
    return function inner(){
        var c = 'local'

        console.log(a + ':' + b + ':' + c)
    }
}
outer()()
複製代碼

在 Chrome 控制檯執行上面代碼,在執行 outer()() 時,aouter 都是全局變量,瀏覽器環境中的全局變量所有掛在全局 window 對象上。b 是閉包變量, 對 temp 函數內定義的函數保持可見。c 是局部變量,只對 inner 函數內部可見。ide

看上去彷佛沒什麼問題,接下來看點有問題的:模塊化

if(true){
    var _a = 1
}
console.log(_a)
複製代碼

正常狀況,_a 應該是 undefined 的纔對,然而不要覺得你覺得就是你覺得的。if 語句塊裏定義的變量 _a 直接變成了全局變量。若是是從C語言,Java等主流編程語言轉過來的就更加迷惑了,這簡直就是TMD不科學。函數

諸如 forwhileswitch 等可接大括號的代碼塊都是不能定義局部變量的,定義的統統是全局變量,可以定義局部變量的只有函數這個第一公民。這不科學,不合理,不符合社會主義核心價值觀\抓狂。學習

一聲霹靂,ES6 落地,完美地彌補了上面 JavaScript 暴露的缺陷。今後之後你能夠覺得你覺得的就是你覺得的了。ES6 爲了向後兼容,var 仍是原來的 var 保持不變,在此基礎上又新添了一個聲明變量的關鍵字 let 和一個聲明常量的關鍵字 const

{
    let a = 1
}
console.log(a)
// Uncaught ReferenceError: a is not defined
複製代碼

完善的做用域機制可有效地避免命名污染,提升程序的可靠性,減小隱晦的bug,尤爲是開發大型多人協做項目時做用尤其明顯。因此最佳實踐就是自始至終地使用 let,而不要再讓 var 這個混小子出如今視線裏。

模塊系統

模塊化,模塊化,模塊化,重要的事情說三遍,這是工程化的第一要務,是控制軟件複雜度的最重要措施,沒有之一。然而 2015 年以前的 JavaScript 語言是沒有模塊系統的。C 有 include,Java 有 import,連 CSS 都有個蹩腳的 @import,wrnmmp,JavaScript 卻只有 undefined。有條件要上,沒條件創造條件也要上。因而乎,JavaScript 社區裏的各位勇士造出了各類各樣實現模塊化的輪子,AMD,CMD,UMD 全蹦出來了。不想用又苦於沒有好的解決方案,只能在心裏吶喊,這不科學,不合理,不符合···\抓狂。

霹靂嘩啦,ES6 落地,帶來了原生的模塊系統,優雅又簡單,絲滑般的體驗沖淡了腰斬給咱帶來的痛,臉上又洋溢出了久違的笑容。

最基本的使用:

/* add.js */
export function add(a, b){
    return a + b
}
複製代碼

上面定義並導出了一個 ES 模塊。接下來就能夠在任一個邏輯文件裏引用:

/* main.js */
import {add} from './add'

add(1, 3)
複製代碼

模塊系統哪家強,ES6 最猖狂。ES6 一出,快刀斬亂麻,直接終結了前端長期的模塊化亂象,實現了大一統。惟一的遺憾是 Node.js 對 ES6 模塊系統的支持還不是無縫過渡。不過這個還好,畢竟 Node.js 的 CommonJS 用起來仍是至關順手的。

有了語言層面的模塊系統,JavaScript 也在語言性質上完成了蛻變,再也不是一個打遍互聯網醬油的小腳本,而成長爲一門舉重若輕的主流編程語言。模塊系統是大型項目不可或缺的標準配置,對項目的開發和維護都很是重要。因此把它列爲 ES6 所帶來的最重要特性絲絕不爲過。

類(Class)

其實這個特性相比前兩個卻是沒那麼重要,說白了,類(Class)作的就是 JS 原型(prototype)作的那點事——繼承,咱以爲這是一個沒它也行,有它更好的語法糖功能。之因此把它列在這是由於咱看 prototype 不爽好久了。

JS 基於原型的繼承機制借鑑自 Self 語言。正如 JS 的設計者所言「它是 C 語言和 Self 語言一晚上情的產物」。原型繼承是很不直觀的,或者能夠說是非主流的。面向對象程序設計中典型的繼承是基於類的繼承,例如 Java,C++ 等主流編程語言實現的均是基於類的繼承。

使用 prototype 會出現 jQuery 的 jQuery.prototype.init.prototype = jQuery.prototype 這種讓人瞬間石化的代碼。何況咱左看右看,上看下看也沒看出來原型繼承相較於類式繼承有什麼優勢可言,反而是越看越拙。咱第一眼看到 prototype 這貨就很不順眼,也許是由於從 C++ 開發過來的緣故吧。

好在 ES6 帶來了 class,不知道你們怎麼看,反正咱內心是樂壞了,有一種久別重逢,相見恨晚感受。

來看個最簡單示例:

/* Point.js */
export class Shape{
    this.x = 0
    this.y = 0
}
複製代碼

英雄聯盟裏的盲僧說過「若是類不是爲了繼承,那將毫無心義」。

import {Point} from "./Point"

class Triangle extends Point{
    constructor(){
        super()
        this.sides = 3
    }
}
let a = new Triangle()
複製代碼

這代碼看着多直觀,多大方,多舒坦。面向對象的概念已經在前端被愈來愈普遍的傳播開來,咱也是很是推崇 class 的繼承方式的,不知道喜歡用哪一個,反正在咱的代碼裏已是看不到 prototype 的影子了。

相關文章
相關標籤/搜索