前后端差異更小了——淺談ES(ECMAScript)6


2015年6月,ES6正式發布。至今一年多的時間內,各個瀏覽器也對支持ES6做出了很大的改善,所以同學們無需顧忌你寫代碼的瀏覽器不認識~

這么久的東西一定早有大神剖析過,今天我們以一個后端菜鳥的視角重新解讀下ES6加入的新語法。

首先很開心,ES6對class(類)的支持上升到了一個新高度,允許構造和繼承,新語法看上來是這樣的:

//繼承
class parent {
    constructor(par) {
        this.Name = par;
        console.log('[父類的構造方法 ' + this.Name + ']');
    }
    sayHello() {
        console.log('父類的sayHello方法 Hello ' + this.Name);
    }
}

class child extends parent {
    constructor(name) {
        super('[子類調用父類的構造 ' + name + ']');
    }
    sayGoodBye() {
        console.log('子類的sayGoobBue方法 GoodBye ' + this.Name);
    }
}

//調用
var a = new parent('Es6');
a.sayHello();
var b = new child('Max');
b.sayHello();
b.sayGoodByr();

 有沒有被驚艷到?(可這的確是個Js文件)運行后的效果是這樣的:

和后端一樣,子類繼承父類需要使用關鍵字extends,繼承后,可以使用關鍵字super調用父類屬性。

並且我發現此處的this在被繼承后也被子類一並帶入,也就是說:this的作用域將會被向下傳遞。(請參照運行結果最后一行。)

上面是class(類)的繼承,有了繼承,我們在構建Js代碼時,就會獲得更強大的能力(可擴展、易維護、易閱讀等)。

可能有些同學會說了:我根本不習慣這樣寫,感覺都不像Js了啊喂!

沒關系,ES6怎么會忘記我們的對象字面量呢?繼承當然也會出現在對象字面量的應用中:

var Es6Parent = {
    cons(mess) {
        console.log('原型Es6Parent的cons方法' + mess);
    }
}
var Es6Child = {
    //設置原型為 Es6Parent ,相當於繼承
    __proto__: Es6Parent,
    work() {
        console.log('下層Es6Child的work方法 I\'m very busy!');
    }
}

//調用
Es6Parent.cons('原型cons方法');
Es6Child.cons('下級調用上層原型的方法');
Es6Child.work();

運行結果如下:

設置的方式也超簡單:使用關鍵字'__proto__'設置原型即可(只不過是給原型鏈換了種叫法而已嘛)

下面介紹一些簡單實用的語法糖,首先是方便的參數設置:

var Name = 'Max';
console.log(`我是很方便帶參數的的波浪符${Name}`);

重點是${},它可以直接在字符串中帶入參數(拼接方便很多有木有),但是需要和波浪符(`)搭配使用才有效哦~

接下來是...語法,當它出現在形參列表內,代表不定量參數:

function show(...all) {
    all.forEach(function (i, v) {
        console.log(`不定量參數的值:${v}`);
    }, all);
}

//調用
show(1,2,3,4,5,6);

運行結果如下:

定義的時候是不是省力很多呢?還有更好用的,當...出現在實參列表內,它將允許直接傳入數組(而不是使用apply):

function sayHi(name, age, sex) {
    console.log(`大家好,我是${name},今年${age}歲,我是${sex}生。`);
}

//調用
var arr = ['小明', 18, '男'];
sayHi(...arr);

運行結果如下:

定義sayHi函數時,寫了3個參數,調用時使用...傳入數組時,它將從0下標開始依次順序匹配參數。

我們在工作中,經常使用回調函數來完成某些操作,但是每次回調都要寫個完整的funciton(好麻煩的說),ES6引入了lambda表達式,大大優化了這一操作:

function callBack(back) {
    back();
}

//兩種調用方式對比
callBack(function () {
    console.log('我是舊的調用方式');
});

callBack(()=>console.log('我是lambda調用方式'));

 運行結果如下:

使用了lambda以后的函數傳入方式是不是更優雅呢?如果比較萌比,那就再來一個對象字面量版本的:

var show_msg = (name, job) => {
    console.log(`大家好,我叫${name},是一名${job}`)
};

//調用
show_msg('暮城','軟件攻城獅');

 運行結果如下:

現在大家應該已經很清楚了:()=>語法呢,=>前面是參數列表,后面是方法體。以后看到類似的語法可別暈~

語法糖還有很多,我先說這么多,因為下面要說更重要的:新數據類型和監聽的實現。

Es6新增了map,set,以及weakMap、weakSet四種類型。

它們都有什么差異呢?先說說map:map以key-value的方式存儲,並且在map內所有的鍵都是唯一的,來看被for in 遍歷后的結果:

var par1 = 'key_1';
var par2 = 'key_2';
var testMap = new Map();
testMap.set(par1, '第一個值');
testMap.set(par2, '第二個值');
testMap.set(par1, '第三個值');
for(i of testMap) {
    console.log(i);
}

可以看到第三個值將第一個值頂替掉而不是共存,原因就是第一個值和第三個值鍵相同。

set和map的差別就在於,它是以value的方式存儲,而且同樣不允許重復值出現:

var par11 = 'value_1';
var par22 = 'value_2';
var testSet = new Set();
testSet.add(par11);
testSet.add(par22);
testSet.add(par11);
for(i of testSet) {
    console.log(i);
}

至於WeakMap和WeakSet,使用方式都一樣,只是這兩種類型的鍵都采用了弱引用,即:作為屬性鍵的對象如果沒有其他地方引用時自動回收(自動釋放)。

此處就不多做解釋,不過我推薦大家使用WeakMap和WeakSet。

現在,我們終於說到了監聽器(監聽器可是重頭戲)

監聽器是很有意思的東西,它給予了我們極大的便利,這一點在實現MVVM模型的操作時尤為重要,ES6中的監聽看上去大概是這樣的:

//被監聽的對象
var ob = { name: 'Max', like: 'women' };
//觸發監聽時的程序
var pro = {
    set: function (cagObj, cagKey, cagValue) {
        console.log(`${cagObj[cagKey]}變為了${cagValue}`);
        cagObj[cagKey] = cagValue;
    }
}
ob = new Proxy(ob, pro);
ob.like = 'man';

set內定義的function將會在監聽對象發生改變時自動觸發,參數列表內的3個值也是默認定義的,它們依次是:被修改的對象、該對象的鍵、該對象的值。

需要注意的是如果你為某元素設定的監聽器觸發后,它原本的修改進程會被阻止(如果你不進行這一步的話),所以需要我們顯式的去修改才可。

運行效果如下:

擁有了這些特性,我們自己想寫一個類似於VUE的數據框架也變得簡單了許多。

另外,ES6還更新了很多命名空間下的函數(如:math),這里就不一一羅列(寫不完並且網上大把)。

最后,ES6的推出讓我直觀感覺到前后端差距進一步縮小,希望有一天Js可以不借助后端完成數據交互~(不要吐槽我學的晚)


免責聲明!

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



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