撩課-Web大前端天天5道面試題-Day30

1.什麼叫優雅降級和漸進加強?

優雅降級:
Web站點在全部新式瀏覽器中都能正常工做,
若是用戶使用的是老式瀏覽器,
則代碼會針對舊版本的IE進行降級處理了,
使之在舊式瀏覽器上以某種形式降級體驗卻不至於徹底不能用。
如:border-shadow

漸進加強:
從被全部瀏覽器支持的基本功能開始,
逐步地添加那些只有新版本瀏覽器才支持的功能,
向頁面增長不影響基礎瀏覽器的額外樣式和功能的。
當瀏覽器支持時,它們會自動地呈現出來併發揮做用。
如:默認使用flash上傳,
但若是瀏覽器支持 HTML5 的文件上傳功能,
則使用HTML5實現更好的體驗;

 

2.舉一些ES6對Object類型作的經常使用升級優化?

優化部分

對象屬性變量式聲明。
ES6能夠直接以變量形式聲明對象屬性或者方法。
比傳統的鍵值對形式聲明更加簡潔,
更加方便,語義更加清晰.

let [apple, orange] = ['red appe', 'yellow orange'];

// let myFruits = {apple: 'red appe', orange: 'yellow orange'};
let myFruits = {apple, orange};   
尤爲在對象解構賦值(見優化部分b.)或者模塊輸出變量時,
這種寫法的好處體現的最爲明顯

let {keys, values, entries} = Object;

// let MyOwnMethods = {keys: keys, values: values, entries: entries}
let MyOwnMethods = {keys, values, entries};

能夠看到屬性變量式聲明屬性看起來更加簡潔明瞭。
方法也能夠採用簡潔寫法

let es5Fun = {
    method: function(){}
}; 

let es6Fun = {
    method(){}
}
對象的解構賦值。 
ES6對象也能夠像數組解構賦值那樣,
進行變量的解構賦值

let {apple, orange} = {apple: 'red appe', orange: 'yellow orange'};

對象的擴展運算符(...)。 
ES6對象的擴展運算符和數組擴展運算符用法本質上差異不大,
畢竟數組也就是特殊的對象。
對象的擴展運算符一個最經常使用也最好用的用處就在於能夠輕鬆的取出
一個目標對象內部所有或者部分的可遍歷屬性,
從而進行對象的合併和分解

let {apple, orange, ...otherFruits} =
{apple: 'red apple', orange: 'yellow orange', grape: 'purple grape', peach: 'sweet peach'}; 
// otherFruits  {grape: 'purple grape', peach: 'sweet peach'}
// 注意: 對象的擴展運算符用在解構賦值時,
// 擴展運算符只能用在最有一個參數(otherFruits後面不能再跟其餘參數)
let moreFruits = {watermelon: 'nice watermelon'};
let allFruits = {apple, orange, ...otherFruits, ...moreFruits};

super 關鍵字。
ES6在Class類裏新增了相似this的關鍵字super。
同this老是指向當前函數所在的對象不一樣,
super關鍵字老是指向當前函數所在對象的原型對象

升級部分

ES6在Object原型上新增了is()方法,
作兩個目標對象的相等比較,

//false實際上是不合理的,Object.is修復了這個小bug。
//(Object.is(NaN, NaN) // true)
用來完善'==='方法。
'==='方法中NaN === NaN 

ES6在Object原型上新增了assign()方法,
用於對象新增屬性或者多個對象合併

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

注意: 
assign合併的對象target只能合併source一、source2中的自身屬性,
並不會合併source一、source2中的繼承屬性,
也不會合並不可枚舉的屬性,
且沒法正確複製get和set屬性(會直接執行get/set函數,取return的值)

ES6在Object原型上新增了getOwnPropertyDescriptors()方法,
此方法加強了ES5中getOwnPropertyDescriptor()方法,
能夠獲取指定對象全部自身屬性的描述對象。
結合defineProperties()方法,
能夠完美複製對象,
包括複製get和set屬性
ES6在Object原型上新增了getPrototypeOf()和setPrototypeOf()方法,
用來獲取或設置當前對象的prototype對象。
這個方法存在的意義在於,
ES5中獲取設置prototype對像是經過__proto__屬性來實現的,
然而__proto__屬性並非ES規範中的明文規定的屬性,
只是瀏覽器各大產商「私自」加上去的屬性,
只不過由於適用範圍廣而被默認使用了,
再非瀏覽器環境中並不必定就能夠使用,
因此爲了穩妥起見,
獲取或設置當前對象的prototype對象時,
都應該採用ES6新增的標準用法
ES6在Object原型上還新增了Object.keys(),
Object.values(),Object.entries()方法,
用來獲取對象的全部鍵、全部值和全部鍵值對數組

 

3.舉一些ES6對Function函數類型作的經常使用升級優化?

優化部分:

箭頭函數(核心)。
箭頭函數是ES6核心的升級項之一,
箭頭函數裏沒有本身的this,
這改變了以往JS函數中最讓人難以理解的this運行機制。

主要優化點:

箭頭函數內的this指向的是函數定義時所在的對象,
而不是函數執行時所在的對象。
ES5函數裏的this老是指向函數執行時所在的對象,
這使得在不少狀況下this的指向變得很難理解,
尤爲是非嚴格模式狀況下,
this有時候會指向全局對象,
這甚至也能夠歸結爲語言層面的bug之一。

ES6的箭頭函數優化了這一點,
它的內部沒有本身的this,這也就致使了this老是指向上一層的this,
若是上一層仍是箭頭函數,則繼續向上指,
直到指向到有本身this的函數爲止,並做爲本身的this
箭頭函數不能用做構造函數,
由於它沒有本身的this,沒法實例化
也是由於箭頭函數沒有本身的this,
因此箭頭函數 內也不存在arguments對象。(能夠用擴展運算符代替)
函數默認賦值。

ES6以前,
函數的形參是沒法給默認值得,
只能在函數內部經過變通方法實現。
ES6以更簡潔更明確的方式進行函數默認賦值

function es6Fuc (x, y = 'default') {
    console.log(x, y);
}
es6Fuc(4) // 4, default

升級部分

ES6新增了雙冒號運算符,
用來取代以往的bind,call,和apply。(瀏覽器暫不支持,Babel已經支持轉碼)

foo::bar;
// 等同於
bar.bind(foo);

foo::bar(...arguments);
// 等同於
bar.apply(foo, arguments);

 

4.Generator函數是什麼,有什麼做用?

若是說JavaScript是ECMAScript標準的一種具體實現、
Iterator遍歷器是Iterator的具體實現,
那麼Generator函數能夠說是Iterator接口的具體實現方式。
執行Generator函數會返回一個遍歷器對象,
每一次Generator函數裏面的yield都至關一次遍歷器對象的next()方法,
而且能夠經過next(value)方法傳入自定義的value,來改變Generator函數的行爲。
Generator函數能夠經過配合Thunk 函數更輕鬆更優雅的實現異步編程和控制流管理。

 

5.什麼是 Babel?

Babel 是一個 JS 編譯器,
自帶一組 ES6 語法轉化器,
用於轉化 JS 代碼。 
這些轉化器讓開發者提早使用最新的 JS語法(ES6/ES7),
而不用等瀏覽器所有兼容。
Babel 默認只轉換新的 JS 句法(syntax),
而不轉換新的API。
 
相關文章
相關標籤/搜索