es6有哪些屬性
問題
常用的es6語法有哪些
問題描述
作爲es6問題的開始的一個問題,想通過這個問題知道對方寫代碼時是否在用es6,是否知道自己用的是es6。但是大部分都說不上來幾個(其實突然問我,我也不一定能說很多,當然面試多了之後就可以隨口就來),所以我都懷疑這個問題有沒有問的必要,對方這個問題其實回答的多少我後面還是該怎麼問還是怎麼問,也並不影響此次面試。
期望答案
- let、const
- 解構賦值
- 末班字符串
- 箭頭函數
- 函數默認值
- promise
- set、map結構
- class類
- symbol
- Iterator 和 for...of 循環.
- 數值的擴展方法
- 數組的擴展方法
- 正則的擴展方法
- 對象的擴展方法
- 。。。。。。 以上爲一些常用到的,還有一些不常用的就不一一列舉了
var、let、const
問題
說下var、let、const的區別
問題描述
一個非常基礎的問題,基本都是回答的差不多,不過有時候會說var和let的區別爲一個沒有作用域一個有作用域,顯然這是一個誤區。const是常量這個都知道,但是他可變的情況就很少有人清楚,阮一峯的《ECMAScript 6 入門》有詳細的說明。
期望答案
- let、const不存在變量提升,var存在變量提升
- let、const不能重複聲明,var可以重複聲明
- let、const有塊級作用域,var沒有塊級作用域
補充:
-
塊級作用域爲 {} 只要被包裹在在{}中都是一個塊級作用域,比如:if、for、function、或者是直接只寫一個{}
-
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
本質: const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明爲常量必須非常小心。
所以const聲明的對象、數組在對內部進行操作時是並不會報錯的,即const聲明的可變情況。
塊級作用域和函數聲明
問題
塊級作用域對函數聲明有什麼影響或改變
問題描述
這個問題我並沒有在面試中問過,因爲這個問題其實很抽象而且很難去說明,而且這個環境問題就很難去模擬,下面是我在查閱了一些文檔和書之後的一些理解,如果有問題,敬請斧正。
阮一峯的《ECMAScript 6 入門》中let、const中有一節是對這一塊的描述。
期望答案
ES5 規定,函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域聲明。但是,瀏覽器沒有遵守這個規定,爲了兼容以前的舊代碼,還是支持在塊級作用域之中聲明函數,不會報錯。
ES5環境下可以實現下面代碼
demo() // 打印 bbb
var flag = true
if (flag) {
function demo() {
console.log('aaa')
}
} else {
function demo() {
console.log('bbb')
}
}
複製代碼
執行此代碼時,會先將函數聲明提升到頂部而並不會根據判斷在下面進行聲明,打印bbb是因爲第一個聲明被第二個聲明覆蓋了(《你不知道的javaScript》第一部分第四章第三節),實際爲下面代碼:
function demo() {
console.log('aaa')
}
function demo() {
console.log('bbb')
}
var flag
demo() // 打印 bbb
flag = true
if (flag) {
} else {
}
複製代碼
ES6 引入了塊級作用域,明確允許在塊級作用域之中聲明函數。ES6規定,塊級作用域之中,函數聲明語句的行爲類似於let,在塊級作用域之外不可引用。
如果改變了塊級作用域內聲明的函數的處理規則,顯然會對老代碼產生很大影響。爲了減輕因此產生的不兼容問題,ES6 在附錄 B裏面規定,瀏覽器的實現可以不遵守上面的規定,有自己的行爲方式。
- 允許在塊級作用域內聲明函數。
- 函數聲明類似於var,即會提升到全局作用域或函數作用域的頭部。
- 同時,函數聲明還會提升到所在的塊級作用域的頭部。
注意,上面三條規則只對 ES6 的瀏覽器實現有效,其他環境的實現不用遵守,還是將塊級作用域的函數聲明當作let處理。
上面代碼的執行順序會變爲
var flag
var demo
demo() // demo is not a function
flag = true
if (flag) {
function demo() {
console.log('aaa')
}
} else {
function demo() {
console.log('bbb')
}
}
複製代碼
promise
問題
一般情況這個問題我會給面試者出一個代碼題
console.log(1)
let promise = new Promise((resolve, reject) => {
console.log(2)
resolve()
console.log(3)
})
setTimeout(() => {
console.log(4)
}, 0);
console.log(5)
promise.then(() => {
console.log(6)
})
console.log(7)
複製代碼
問題描述
正確執行順序我會放在期望答案的最後,防止在看題時看到結果。
這個問題主要問的是兩個關鍵點:1. promise在構造時內部就已經執行結束。2. promise.then和setTimeout的執行順序
期望答案
關鍵點1:在Promise對象new的時候,Promise內部resolve前後就都執行了,resolve只與then有關(resolve調用時的參數爲then的參數),並不會阻止後面代碼的執行。
關鍵點2:promise.then的執行時間會早於setTimeout,promise和setTimeout都可以處理異步問題,promise爲微任務setTimeout爲宏任務,promise.then會在本次任務的最後的去調用,而setTimeout會開啓一個新的任務去執行其內部的內容,即下一次任務的開始。所以6比4先打印。
問題執行結果:1 2 3 5 7 6 4