Part1 · JavaScript【深度剖析】
ES 新特性與 TypeScript、JS 性能優化
文章說明:本專欄內容為本人參加【拉鉤大前端高新訓練營】的學習筆記以及思考總結,學徒之心,僅為分享,如若有誤,請在評論區支出,如果您覺得專欄內容還不錯,請點贊、關注、評論,
共同進步!
上一篇:【JavaScript異步編程】、【手寫promise】
一、ECMAScript概述
ECMAScript,即 ECMA-262 定義的語言,并不局限于 Web 瀏覽器,事實上,這門語言沒有輸入和輸出之類的方法,ECMA-262 將這門語言作為一個基準來定義,以便在它之上再構建更穩健的腳本語言,
Web 瀏覽器只是 ECMAScript 實作可能存在的一種宿主環境(host environment),宿主環境提供ECMAScript 的基準實作和與環境自身互動必需的擴展,擴展(比如 DOM)使用 ECMAScript 核心型別和語法,提供特定于環境的額外功能,其他宿主環境還有服務器端 JavaScript 平臺 Node.js 和即將被淘汰的 Adobe Flash,
日常使用的Web環境下,JavaScript語言包括:ECMAScript、瀏覽器提供的BOM物件、DOM樹,
Node.js環境下,JavaScript包括:ECMAScript、Node API(fs、net、etc.)
歷史版本:
二、ES2015概述
ECMA-262 闡述了什么是 ECMAScript 符合性,要成為 ECMAScript 實作,必須滿足下列條件:
-
支持 ECMA-262 中描述的所有“型別、值、物件、屬性、函式,以及程式語法與語意”;
-
支持 Unicode 字符標準,
此外,符合性實作還可以滿足下列要求,
-
增加 ECMA-262 中未提及的“額外的型別、值、物件、屬性和函式”,ECMA-262 所說的這些額外內容主要指規范中未給出的新物件或物件的新屬性,
-
支持 ECMA-262 中沒有定義的“程式和正則運算式語法”(意思是允許修改和擴展內置的正則運算式特性),
以上條件為實作開發者基于 ECMAScript 開發語言提供了極大的權限和靈活度,也是其廣受歡迎的原因之一,
三、ES2015 let 與塊級作用域
具體詳情請閱讀《JavaScript高級程式設計·第四版》中的第三章第三節(3.3)
1.var
- var定義的變數會預決議,簡單的說就是如果變數沒有定義就直接使用的話,JavaScript回去決議這個變數,代碼不會報錯,只會輸出undefined,
console.log(foo) // undefined
var foo = 'foo';
- var定義的變數可以反復去定義,當然后面的會覆寫前面的
var a = 1;
var a = 2;
- var在回圈中使用的時候,回圈體外依然可以使用
for (var i = 0; i < 3; i++) {
for (var i = 0; i < 3; i++) {
console.log(i)
}
console.log('內層結束 i = ' + i)
}
//0
//1
//2
//內層結束 i = 3
- 在回圈系結事件程序中,var定義的變數無法保存,回圈會在瞬間執行完
var elements = [{}, {}, {}]
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = (function (i) {
return
})
}
elements[1].onclick()
2.let
- let定義的變數不會預決議,必須先宣告再使用,否則會報錯
console.log(b); // 報錯
let b = 'bar'
- let不能定義已經定義過的變數(無論之前是用var定義的還是let或者const定義的)
let b = 3;
let b = 4; // 報錯
- let是塊級作用域,函式內部使用let定義后,對函式外部無影響,簡單說就是在一個{}里面生效
for (let i = 0; i < 3; i++) {
let i = 'foo';
console.log(i) // foo
}
- 由于let是塊級作用域,在回圈系結事件程序中let會在這個回圈中生效,再次回圈時let會重新定義生效
let elements = [{}, {}, {}]
for (let i = 0; i < elements.length; i++) {
elements[i].onclick = (function (i) {
console.log(i)
})
}
elements[0].onclick()
四、ES2015 const
- const定義的變數不會預決議,必須先宣告再使用,否則會報錯
console.log(a); // 報錯 undefined
const a = 'foo';
-
const定義的變數不允許修改
const a = 5; a = 6; // err- 但是,在陣列里面,const的值是允許被修改的,這是因為const存盤的是地址,值的內容可以變化
const arr = [1,2,3,4,5] arr[1] = 'array' console.log(arr);
五、ES2015 陣列的解構
ECMAScript2015 新增了一種從陣列或者物件獲取指定元素的快捷方式,這是一種新的語法,這種新語法叫做解構,如下代碼所示,定義一個陣列:
const arr = [100, 200, 300]
const foo = arr[0]
const bar = arr[1]
const baz = arr[2]
console.log(foo, bar, baz)
在 ECMAScript2015 之前想要獲取這個陣列中的元素,需要通過索引訪問對應的值,然后將訪問的結果賦值給一個變數,
而在 ECMAScript2015 之后,可以通過陣列的解構這種方式快速獲取陣列中的指定成員,如下代碼所示:
const arr = [100, 200, 300]
const [foo, bar, baz] = arr
console.log(foo, bar, baz)
這里會根據變數的位置進行分配陣列中對應位置的成員,如果只要獲取某一個位置上的成員,比如上個陣列中的最后一個位置的成員,只需要保留前兩個占位就可以了,如下代碼所示:
const arr = [100, 200, 300]
const [, , baz] = arr
console.log(baz)
除此之外,還可以在變數名前面增加 ... 來獲取從當前位置到陣列最后的所有成員,如下代碼所示:
const arr = [100, 200, 300]
const [foo, ...rest] = arr
console.log(rest) // [ 200, 300 ]
這里需要注意的是,這種解構的用法只能在成員變數的最后一個變數上才能使用,
如果解構的變數數量少于陣列的成員數量的話,那會按照從前到后的順序進行獲取,如下代碼所示:
const arr = [100, 200, 300]
const [foo] = arr
console.log(foo) // 100
從列印的結果可以看到,陣列中剩下的成員都不會被獲取到,反之,如果解構的變數數量多于陣列的成員數量的話,那多出來的變數的值為 undefined,如下代碼所示:
const arr = [100, 200, 300]
const [foo, bar, baz, more] = arr
console.log(more) // undefined
使用 ECMAScript2015 之后的解構將大大進行簡化,如下代碼所示:
const path = 'foo/bar/baz'
const [, rootDir] = path.split('/')
console.log(rootDir)
六、ES2015 物件的解構
在 ECMAScript2015 中,除了陣列可以被解構之外,物件同樣也可以被解構,只不過物件的解構,是需要通過屬性名來獲取,而不是位置,如下代碼所示:
const obj = {
name: '拉勾大前端',
age: 3
}
const {
name
} = obj
console.log(name)
上述代碼的運行結果如下:
拉勾大前端
這里解構中的變數名還有一個很重要的作用,就是匹配解構物件中的成員,從而獲取指定成員的值,比如上述代碼結構總的 name 獲取了 obj 物件中的 name 屬性值,
因為物件的解構的這種特性,如果當前作用域中存在一個同名的變數,就會產生沖突,如下代碼所示:
const obj = {
name: '拉勾大前端',
age: 3
}
const name = '拉勾大前端2'
const {
name
} = obj
console.log(name)
上述代碼的運行結果如下:
object-destructuring.js:13
name
^
SyntaxError: Identifier 'name' has already been declared
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:599:28)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
因為 obj 物件的 name 屬性必須在解構中定義 name 變數進行獲取,那么這一沖突就無法避免,這個時候可以通過重命名的方式來解決這樣的問題,如下代碼所示:
const obj = {
name: '拉勾大前端',
age: 3
}
const name = '拉勾大前端'
const {
name: objName
} = obj
console.log(objName)
如上述代碼所示,解構中原本的 name 對應著 obj 物件的 name 屬性,objName 是重命名的變數名,從而解決了同名的沖突,如下圖所示:
今日分享截止到這里,明天繼續更新后續部分:模板字串、引數默認值、剩余引數等,
記錄:2020/11/03
下一篇:模板字串、引數默認值、剩余引數
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/203130.html
標籤:AI
上一篇:script 元素,重繪與回流
下一篇:你需要知道的網頁全屏背景小知識
