面試時面試官想要聽到什麼答案(關於es6中let、const、promise、塊級作用域的問題)

es6有哪些屬性

問題

常用的es6語法有哪些

問題描述

作爲es6問題的開始的一個問題,想通過這個問題知道對方寫代碼時是否在用es6,是否知道自己用的是es6。但是大部分都說不上來幾個(其實突然問我,我也不一定能說很多,當然面試多了之後就可以隨口就來),所以我都懷疑這個問題有沒有問的必要,對方這個問題其實回答的多少我後面還是該怎麼問還是怎麼問,也並不影響此次面試。

期望答案

  1. let、const
  2. 解構賦值
  3. 末班字符串
  4. 箭頭函數
  5. 函數默認值
  6. promise
  7. set、map結構
  8. class類
  9. symbol
  10. Iterator 和 for...of 循環.
  11. 數值的擴展方法
  12. 數組的擴展方法
  13. 正則的擴展方法
  14. 對象的擴展方法
  15. 。。。。。。 以上爲一些常用到的,還有一些不常用的就不一一列舉了

var、let、const

問題

說下var、let、const的區別

問題描述

一個非常基礎的問題,基本都是回答的差不多,不過有時候會說var和let的區別爲一個沒有作用域一個有作用域,顯然這是一個誤區。const是常量這個都知道,但是他可變的情況就很少有人清楚,阮一峯的《ECMAScript 6 入門》有詳細的說明。

期望答案

  1. let、const不存在變量提升,var存在變量提升
  2. let、const不能重複聲明,var可以重複聲明
  3. let、const有塊級作用域,var沒有塊級作用域

補充:

  1. 塊級作用域爲 {} 只要被包裹在在{}中都是一個塊級作用域,比如:if、for、function、或者是直接只寫一個{}

  2. 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裏面規定,瀏覽器的實現可以不遵守上面的規定,有自己的行爲方式。

  1. 允許在塊級作用域內聲明函數。
  2. 函數聲明類似於var,即會提升到全局作用域或函數作用域的頭部。
  3. 同時,函數聲明還會提升到所在的塊級作用域的頭部。

注意,上面三條規則只對 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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章