Node.js筆記七:es6
es6是javascript的新一代語法規(guī)范三圆,現(xiàn)在很多新的庫都是基于新的es6語法規(guī)范編寫顾稀。得益于類結構博肋,方便了大型項目的編寫汪厨。在webpack赃春,babel等工具的幫助下,es6離我們并不遙遠劫乱。說到es6不得不說es5织中,也想說說es7。
網(wǎng)上es6的教程很多衷戈,這里推薦的是阮一峰老師的ECMAScript 6 入門狭吼。
es5
我相信很多的前端工程師嘴上說的Javascript都是es5,因為es5可以直接在大部分瀏覽器當中運行殖妇,兼容性問題較少刁笙。由于es5當中所有數(shù)據(jù)類型都是對象,并不存在類的概念,只有原型采盒。所有的原型鏈都指向Object旧乞。
這時,面試官問你磅氨,用原始es5寫一個class類名為person尺栖,它具有公有屬性name,和私有屬性age烦租,公有函數(shù)setAge()設置私有變量age延赌,公有函數(shù)getAge()獲取變量age。
function Person(props){
if(props){
this.name = props.name||"brandon";
var age = props.age||26;
}else{
this.name = "brandon";
var age = 26;
}
this.setAge = function(_age){
age = _age;
}
this.getAge = function(){
return age;
}
}
其中叉橱,this指向的是自己的prototype挫以。在進行new操作以后,該對象的屬性可以被外部讀取窃祝,便像是公有變量掐松。而var定義的變量不能被外部讀取,可以看作私有變量粪小。
這里補充一點大磺,new的過程其實并不是類的實例化。而是構造函數(shù)執(zhí)行的過程探膊,將this的屬性賦予新的對象杠愧。
面試官再問你,寫一個class類名為teacher繼承于person逞壁,具有私有屬性studentCount公有方法setStudentCount()設置私有變量studentCount流济,公有函數(shù)getStudentCount()獲取變量studentCount。沒有類怎么辦腌闯?
function Teacher(props){
Person.call(this, props);
if(props){
var studentCount = props.studentCount||55;
}else{
var studentCount = 55;
}
this.setStudentCount = function(_count){
studentCount = _count;
}
this.getStudentCount = function(){
return studentCount;
}
}
這不過是個構造函數(shù)绳瘟。原型鏈并沒有建立。步驟如下:需要創(chuàng)建一個新的函數(shù)姿骏,原型指向父類稽荧。子類原型是它的實例。詳細參考:原型繼承-廖雪峰Javascript官網(wǎng)工腋。源碼參考姨丈。其實,es5面向?qū)ο蟮姆椒ㄟ€有很多擅腰,想了解各自優(yōu)劣蟋恬,參看Javascript面向?qū)ο缶幊蹋ǘ簶嬙旌瘮?shù)的繼承。
function inherits(Child,Parent){
var F = function(){};
F.prototype =Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
inherits(Teacher, Person);
這時候趁冈,面試官再問你歼争,es5怎么實現(xiàn)多繼承拜马。
function Man(){
var sex = 'male'
this.setSex = function(_sex){
sex = _sex
}
this.getSex = function(){
return sex
}
}
function Student(){
Person.call(this)
Man.call(this)
}
for(var i in Person.prototype){
Student.prototype[i] = Person.prototype[i]
}
for(var i in Man.prototype){
Student.prototype[i] = Man.prototype[i]
}
由于空方法繼承法在多繼承的情況下會出現(xiàn)被覆蓋的情況。最終只能使用復制法沐绒。該方法將父類的prototype復制給子類俩莽,出現(xiàn)名字重復的話,直接被覆蓋乔遮。
es6
如果你困擾于es5的面向?qū)ο蟀绯兞刻嵘瘮?shù)提升和作用域的問題蹋肮,那么es6則是你的救星出刷。es6也就是es2015。它給你一個完整的編程語言坯辩。
數(shù)據(jù)類型
var
是es5變量聲明的一個標志馁龟。它出現(xiàn)的時候你要小心,因為變量提升漆魔。它沒出現(xiàn)的時候坷檩,你更加需要小心,它有可能改變了上一層作用域的值改抡。
es5只有全局作用域和函數(shù)作用域矢炼,沒有塊級作用域。
--30分鐘掌握ES6/ES2015核心內(nèi)容
es6的let
和const
則沒有這個問題雀摘,他倆給你的是類似其他語言般正常的體驗,使用的是塊級作用域八拱。
let
是變量聲明阵赠,并不會出現(xiàn)變量提升,而且可以在for循環(huán)中放心使用肌稻。const
則為常量聲明清蚀,已經(jīng)定義不能可以被改變,很好地避免了變量的重復聲明爹谭。
面向?qū)ο?/h3>
es6提供完整的class和繼承枷邪,但是很可惜的是并不具備私有變量。如下的定義_age
并非正在的私有變量诺凡。_age
還是可以被外界訪問东揣。上方的面向?qū)ο蟠a可以被重構。
class Person {
constructor(){
this.name = 'brandon'
this._age = 26;
}
setAge(_a){
this._age = _a;
}
getAge(){
return this._age;
}
}
繼承用extends腹泌,super則是執(zhí)行父類的構造函數(shù)嘶卧。
class Teacher extends Person {
constructor(){
super()
this._studentCount = 55
}
setStudentCount(_b){
this._studentCount = _b
}
getStudentCount(){
return this._studentCount
}
}
如果真的需要私有變量,可以考慮用weakMap
凉袱。詳情參考如何在 ES6 中管理類的私有數(shù)據(jù)芥吟。這里不做詳細說明侦铜。
箭頭函數(shù)
箭頭函數(shù)內(nèi)部沒有constructor方法,也沒有prototype钟鸵,所以不支持new操作钉稍。但是它對this的處理與一般的普通函數(shù)不一樣。箭頭函數(shù)的 this 始終指向函數(shù)定義時的 this棺耍,而非執(zhí)行時贡未。使用前要搞清楚this的指向。
其他特征
解構烈掠,默認參數(shù)和字符串格式化都非常實用羞秤,參考ECMAScript 6 入門。
es7
正因為es6還是有缺點左敌,所以才要有進步瘾蛋。
展望es7,es7在es6的基礎上矫限,它增加了一些新的語言特性哺哼。可以說叼风,es7是es2016發(fā)展的過程中取董,有好幾個stage。
語法特性包括:
- 指數(shù)運算符
- SIMD.JS – SIMD APIs + polyfill
- 異步函數(shù)
- Object.values/Object.entries
- 字符串填充
- 函數(shù)參數(shù)列表與調(diào)用中的尾逗號
由于es7還在發(fā)展的過程中无宿,很多“語法糖”特性并未穩(wěn)定茵汰。暫時不推薦用于生產(chǎn)當中。題外話孽鸡,著名的koa是基于es6開發(fā)的蹂午,而koa2結合es7的await和async的屬性實現(xiàn)異步函數(shù)。