一、let和const
在JavaScript中咱們以前主要用關鍵var來定義變量,ES6之後,新增了定義變量的兩個關鍵字,分別是let和const。
對於變量來說,在ES5中var定義的變量會提升到作用域中所有的函數與語句前面,而ES6中let定義的變量則不會,let聲明的變量會在其相應的代碼塊中建立一個暫時性死區,直至變量被聲明。
let和const都能夠聲明塊級作用域,用法和var是類似的,let的特點是不會變量提升,而是被鎖在當前塊中。
一個非常簡單的例子:
唯一正確的使用方法:先聲明,再訪問。
const
聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。
const雖然是常量,不允許修改默認賦值,但如果定義的是對象Object,那麼可以修改對象內部的屬性值。
const和let的異同點
相同點:const和let都是在當前塊內有效,執行到塊外會被銷毀,也不存在變量提升(TDZ),不能重複聲明。
不同點:const不能再賦值,let聲明的變量可以重複賦值。
const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
塊級作用域的使用場景
除了上面提到的常用聲明方式,我們還可以在循環中使用,最出名的一道面試題:循環中定時器閉包的考題
在for循環中使用var聲明的循環變量,會跳出循環體污染當前的函數。
在實際開發中,我們選擇使用var、let還是const,取決於我們的變量是不是需要更新,通常我們希望變量保證不被惡意修改,而使用大量的const。使用const聲明,聲明一個對象的時候,也推薦使用const,當你需要修改聲明的變量值時,使用let,var能用的場景都可以使用let替代。
symbol
ES6 以前,我們知道5種基本數據類型分別是Undefined,Null,Boolean,Number以及String,然後加上一種引用類型Object構成了JavaScript中所有的數據類型,但是ES6出來之後,新增了一種數據類型,名叫symbol,像它的名字表露的一樣,代表著獨一無二,意思是每個 Symbol類型都是獨一無二的,不與其它 Symbol 重複。
可以通過調用 Symbol() 方法將創建一個新的 Symbol 類型的值,這個值獨一無二,不與任何值相等。
二、字符串
ES6字符串新增的方法
UTF-16碼位:ES6強制使用UTF-16字符串編碼。關於UTF-16的解釋請自行百度了解。
codePointAt():該方法支持UTF-16,接受編碼單元的位置而非字符串位置作為參數,返回與字符串中給定位置對應的碼位,即一個整數值。
String.fromCodePoiont():作用與codePointAt相反,檢索字符串中某個字符的碼位,也可以根據指定的碼位生成一個字符。
normalize():提供Unicode的標準形式,接受一個可選的字符串參數,指明應用某種Unicode標準形式。
在ES6中,新增了3個新方法。每個方法都接收2個參數,需要檢測的子字符串,以及開始匹配的索引位置。
模板字符串
字符串是JavaScript中基本類型之一,應該算是除了對象之外是使用最為頻繁的類型吧,字符串中包含了例如substr,replace,indexOf,slice等等諸多方法,ES6引入了模板字符串的特性,用反引號來表示,可以表示多行字符串以及做到文本插值(利用模板占位符)。
可以用${}來表示模板占位符,可以將你已經定義好的變量傳進括弧中,例如:
includes(str, index):如果在字符串中檢測到指定文本,返回true,否則false。
startsWith(str, index):如果在字符串起始部分檢測到指定文本,返回true,否則返回false。
endsWith(str, index):如果在字符串的結束部分檢測到指定文本,返回true,否則返回false。
如果你只是需要匹配字符串中是否包含某子字符串,那麼推薦使用新增的方法,如果需要找到匹配字符串的位置,使用indexOf()。
三、函數
函數的默認參數
在ES5中,我們給函數傳參數,然後在函數體內設置默認值,如下面這種方式。
在ES6中,我們使用新的默認值寫法
四、箭頭函數(=>)
(箭頭函數比較重要,現在簡單提一下,遲一點有空專門寫一篇箭頭函數的文章。)
箭頭函數中this的使用跟普通函數也不一樣,在JavaScript的普通函數中,都會有一個自己的this值,主要分為:
普通函數:
1、函數作為全局函數被調用時,this指向全局對象
2、函數作為對象中的方法被調用時,this指向該對象
3、函數作為構造函數的時候,this指向構造函數new出來的新對象
4、還可以通過call,apply,bind改變this的指向
箭頭函數:
1、箭頭函數沒有this,函數內部的this來自於父級最近的非箭頭函數,並且不能改變this的指向。
2、箭頭函數沒有super
3、箭頭函數沒有arguments
4、箭頭函數沒有new.target綁定。
5、不能使用new
6、沒有原型
7、不支持重複的命名參數。
箭頭函數的簡單理解
1、箭頭函數的左邊表示輸入的參數,右邊表示輸出的結果。
2、在箭頭函數中,this屬於詞法作用域,直接由上下文確定,對於普通函數中指向不定的this,箭頭函數中處理this無疑更加簡單,如下:
3、箭頭函數中沒有arguments(我們可以用rest參數替代),也沒有原型,也不能使用new 關鍵字,例如:
4、箭頭函數給數組排序
尾調用優化
尾調用是指在函數return的時候調用一個新的函數,由於尾調用的實現需要存儲到內存中,在一個循環體中,如果存在函數的尾調用,你的內存可能爆滿或溢出。
ES6中,引擎會幫你做好尾調用的優化工作,你不需要自己優化,但需要滿足下面3個要求:
1、函數不是閉包
2、尾調用是函數最後一條語句
3、尾調用結果作為函數返回
尾調用實際用途——遞歸函數優化
在ES5時代,我們不推薦使用遞歸,因為遞歸會影響性能。
但是有了尾調用優化之後,遞歸函數的性能有了提升。
五、ES6對象新增方法
Object.assign()
Object.assign()方法用於將所有可枚舉屬性的值從一個或多個源對象複製到目標對象。它將返回目標對象。
Object.assign 方法只會拷貝源對象自身的並且可枚舉的屬性到目標對象。該方法使用源對象的[[Get]]和目標對象的[[Set]],所以它會調用相關 getter 和 setter。因此,它分配屬性,而不僅僅是複製或定義新的屬性。如果合併源包含getter,這可能使其不適合將新屬性合併到原型中。為了將屬性定義(包括其可枚舉性)複製到原型,應使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
String類型和 Symbol 類型的屬性都會被拷貝。
合併對象
合併具有相同屬性的對象
六、Map和Set
Map和Set都叫做集合,但是他們也有所不同。Set常被用來檢查對象中是否存在某個鍵名,Map集合常被用來獲取已存的信息。
Set是有序列表,含有相互獨立的非重複值。
Array和Set對比
都是一個存儲多值的容器,兩者可以互相轉換,但是在使用場景上有分別。如下:
Array的indexOf方法比Set的has方法效率低下
Set不含有重複值(可以利用這個特性實現對一個數組的去重)
Set通過delete方法刪除某個值,而Array只能通過splice。兩者的使用方便程度前者更優
Array的很多新方法map、filter、some、every等是Set沒有的(但是通過兩者可以互相轉換來使用)
Object和Map對比
Object是字符串-值,Map是值-值
Object鍵為string類型,Map的鍵是任意類型
手動計算Object尺寸,Map.size可以獲取尺寸
Map的排序是插入順序
Object有原型,所以映射中有一些預設的鍵。可以理解為Map=Object.create(null)
Set操作集合
Map的方法集合
七、疊代器(Iterator)
1、entries() 返回疊代器:返回鍵值對
2、values() 返回疊代器:返回鍵值對的value
3、keys() 返回疊代器:返回鍵值對的key
雖然上面列舉了3種內建的疊代器方法,但是不同集合的類型還有自己默認的疊代器,在for of中,數組和Set的默認疊代器是values(),Map的默認疊代器是entries()。
for of循環解構
對象本身不支持疊代,但是我們可以自己添加一個生成器,返回一個key,value的疊代器,然後使用for of循環解構key和value。
字符串疊代器
ES6給數組添加了幾個新方法:find()、findIndex()、fill()、copyWithin()
1、find():傳入一個回調函數,找到數組中符合當前搜索規則的第一個元素,返回它,並且終止搜索。
2、findIndex():傳入一個回調函數,找到數組中符合當前搜索規則的第一個元素,返回它的下標,終止搜索。
3、fill():用新元素替換掉數組內的元素,可以指定替換下標範圍。
4、copyWithin():選擇數組的某個下標,從該位置開始複製數組元素,默認從0開始複製。也可以指定要複製的元素範圍。
ES6中類class、Promise與異步編程、代理(Proxy)和反射(Reflection)API,這幾塊內容比較複雜,以後有機會再詳細寫。
來自:沉靜地閃光
https://zhuanlan.zhihu.com/p/43890979