【乾貨分享】前端面試知識點錦集02(JavaScript篇)—— 附答案
1. JavaScript是一門什麼樣的語言,它有哪些特點?
參考答案
JavaScript是一種指令碼語言,官方名稱為ECMAScript(因定義語言的標準為ECMA-262)
。JS的主要特點:
a,語法類似於常見的高階語言,如C和Java;
b,指令碼語言,不需要編譯就可以由直譯器直接執行;
c,變數鬆散定義,屬於弱型別語言;
d,面向物件的
。JS最初是為網頁設計而開發的,現在也是Web開發的重要語言。它支援對瀏覽器(瀏覽器物件模型,BOM)和HTML文件(文件物件模型,DOM)進行操作而使網頁呈現動態的互動特性。
嚴格的說,JS只是ECMAScript中的一種實現,是ECMAScript的和BOM,DOM組成的一種Web開發技術。
2. JavaScript的資料型別有哪些?
參考答案
基本資料型別:字串String,數字Number,布林Boolean
複合資料型別:陣列陣列,物件Object
特殊資料型別:Null空物件,Undefined未定義
3.根據你的理解,請簡述的JavaScript指令碼的執行原理?
參考答案
JavaScript是一種動態,弱型別,基於原型的語言,通過瀏覽器可以直接執行。
當瀏覽器遇到<script>標記的時代,瀏覽器會執行之間的javascript程式碼。嵌入的js程式碼是順序執行的,每個指令碼定義的全域性變數和函式,都可以被後面執行的指令碼所呼叫。變數的呼叫,必須是前面已經宣告,否則獲得的變數值是undefined。
4. 請你談談Cookie的弊端
參考答案
cookie雖然在持久儲存客戶端資料提供了方便,分擔了伺服器儲存的負擔,但還是有很多侷限性的。
第一:每個特定的域名下最多生成20個cookie
1.IE6或更低版本最多20個cookie
2.IE7和之後的版本最後可以有50個cookie。
3.Firefox最多50個cookie
4.chrome和Safari沒有做硬性限制
IE和Opera 會清理近期最少使用的cookie,Firefox會隨機清理cookie。
cookie的最大大約為4096位元組,為了相容性,一般不能超過4095位元組。
IE 提供了一種儲存可以持久化使用者資料,叫做 userData,從IE5.0就開始支援。每個資料最多128K,每個域名下最多1M。這個持久化資料放在快取中,如果快取沒有清理,那麼會一直存在。
優點:極高的擴充套件性和可用性
1.通過良好的程式設計,控制儲存在cookie中的session物件的大小。
2.通過加密和安全傳輸技術(SSL),減少cookie被破解的可能性。
3.只在cookie中存放不敏感資料,即使被盜也不會有重大損失。
4.控制cookie的生命期,使之不會永遠有效。偷盜者很可能拿到一個過期的cookie。
缺點:
1.`Cookie`數量和長度的限制。每個domain最多隻能有20條cookie,每個cookie長度不能超過4KB,否則會被截掉。
2.安全性問題。如果cookie被人攔截了,那人就可以取得所有的session資訊。即使加密也與事無補,因為攔截者並不需要知道cookie的意義,他只要原樣轉發cookie就可以達到目的了。
3.有些狀態不可能儲存在客戶端。例如,為了防止重複提交表單,我們需要在伺服器端儲存一個計數器。如果我們把這個計數器儲存在客戶端,那麼它起不到任何作用。
5. 請你說說cookie 和session 的區別?
參考答案
(1)、cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上。
(2)、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
(3)、session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能
考慮到減輕伺服器效能方面,應當使用COOKIE。
(4)、單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個站點最多儲存20個cookie。
所以個人建議:
將登陸資訊等重要資訊存放為session中。
其他資訊如果需要保留,可以放在Cookie中。
6. 簡單說一下瀏覽器本地儲存是怎樣的
參考答案
在較高版本的瀏覽器中,js提供了sessionStorage和globalStorage。在HTML5中提供了localStorage來取代globalStorage。
html5中的Web Storage包括了兩種儲存方式:sessionStorage和localStorage。
sessionStorage用於本地儲存一個會話(session)中的資料,這些資料只有在同一個會話中的頁面才能訪問並且當會話結束後資料也隨之銷燬。因此sessionStorage不是一種持久化的本地儲存,僅僅是會話級別的儲存。
而localStorage用於持久化的本地儲存,除非主動刪除資料,否則資料是永遠不會過期的。
7. web storage和cookie的區別
參考答案
Web Storage的概念和cookie相似,區別是它是為了更大容量儲存設計的。Cookie的大小是受限的,並且每次你請求一個新的頁面的時候Cookie都會被髮送過去,這樣無形中浪費了頻寬,另外cookie還需要指定作用域,不可以跨域呼叫。
除此之外,Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie需要前端開發者自己封裝setCookie,getCookie。
但是Cookie也是不可以或缺的:Cookie的作用是與伺服器進行互動,作為HTTP規範的一部分而存在 ,而Web Storage僅僅是為了在本地“儲存”資料而生
瀏覽器的支援除了IE7及以下不支援外,其他標準瀏覽器都完全支援(ie及FF需在web伺服器裡執行),值得一提的是IE總是辦好事,例如IE7、IE6中的UserData其實就是javascript本地儲存的解決方案。通過簡單的程式碼封裝可以統一到所有的瀏覽器都支援web storage。
localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等
8. DOM操作怎樣新增、移除、移動、複製、建立和查詢節點?
參考答案
1. 建立新節點
createDocumentFragment() // 建立一個DOM片段 createElement() // 建立一個具體的元素 createTextNode() // 建立一個文字節點
2. 新增、移除、替換、插入
appendChild() removeChild() replaceChild() insertBefore() // 在已有的子節點前插入一個新的子節點
3. 查詢
getElementsByTagName() // 通過標籤名稱 getElementsByName() // 通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等於name值的) getElementById() // 通過元素Id,唯一性
9. 已知ID的Input輸入框,如何獲取這個輸入框的輸入值?(不使用第三方框架)
參考答案
document.getElementById("ID").value
10. 執行緒與程序的區別
參考答案
1. 一個程式至少有一個程序,一個程序至少有一個執行緒
2. 執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高
3. 另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率
4. 執行緒在執行過程中與程序還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制
5. 從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配。這就是程序和執行緒的重要區別
11. null和undefined的區別?
參考答案
null是一個表示"無"的物件,轉為數值時為0
undefined是一個表示"無"的原始值,轉為數值時為NaN
當宣告的變數還未被初始化時,變數的預設值為undefined
null用來表示尚未存在的物件,常用來表示函式企圖返回一個不存在的物件
undefined表示 “缺少值”,就是此處應該有一個值,但是還沒有定義。
典型用法是:
1. 變數被聲明瞭,但沒有賦值時,就等於 undefined
2. 呼叫函式時,應該提供的引數沒有提供,該引數等於 undefined
3. 物件沒有賦值的屬性,該屬性的值為 undefined
4. 函式沒有返回值時,預設返回 undefined
null表示“沒有物件”,即該處不應該有值。典型用法是:
1. 作為函式的引數,表示該函式的引數不是物件
2. 作為物件原型鏈的終點null的使用場景:
1.手動設定變數的值或者物件的某一個屬性值為null;
2.在JS的DOM元素獲取中,如果沒有獲取到指定的元素物件,結果是null;
3.Object.protype.proto的值也為null;
4.正則捕獲階段的時候,如果沒有捕獲到值也是null
undefined的使用場景:
1.變數提升,只宣告未定義,預設值為undefined;
2.嚴格模式下,沒有明確的執行主體,this就是undefined;
3.物件沒有這個屬性名,屬性值就為undefined;
4.函式定義形參不傳值,預設就是undefined;
5.函式沒有返回值(沒有return)時;
12. new操作符具體幹了什麼呢?
參考答案
1. 建立一個空物件,並且 this 變數引用該物件,同時還繼承了該函式的原型
2. 屬性和方法被加入到 this 引用的物件中
3. 新建立的物件由 this 所引用,並且最後隱式的返回 this
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
13. 對JSON 的瞭解?
參考答案
回答一:
a、JSON物件:以“{”開始,以“}”結束,裡面則是一系列的鍵(key)值(value)對,鍵和值用“:”分開,每對鍵值對之間用“,”分開。參考以下語法結構:{key1:value1,key2:value2,key3:value3…}其中鍵(key)是字串,而值(value)可以是字串,數值,true,false,null,物件或陣列,也就是說某個鍵(key)的值(value)可以是一個數組,數組裡面又是一些JSON物件,這種表示稍微複雜一些,但是參照這些理解可以很容易分辨出來。
b、JSON陣列:以”[”開始,”]”結束,如同程式語言一樣,例如C#,Button[] btnArray,則BtnArray是一個Button型別的陣列,裡面就存放Button型別的物件,那麼JSON陣列也一樣,裡面存放的也是JSON物件.
回答二:
a、JSON 指的是 JavaScript 物件表示法(JavaScript Object Notation)
b、JSON 是輕量級的文字資料交換格式,並不是程式語言
c、JSON 獨立於語言存在
d、JSON 具有自我描述性,更易理解
e、JSON 可以將 JavaScript 物件中表示的一組資料轉換為字串,然後就可以在函式之間輕鬆地傳遞這個字串,或者在非同步應用程式中將字串從 Web 客戶機傳遞給伺服器端程式。這個字串看起來有點兒古怪,但是JavaScript很容易解釋它,而且 JSON 可以表示比"名稱 / 值對"更復雜的結構。例如,可以表示陣列和複雜的物件,而不僅僅是鍵和值的簡單列表
回答三:
JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。
它是基於JavaScript的一個子集。資料格式簡單, 易於讀寫, 佔用頻寬小.
json簡單說就是javascript中的物件和陣列,所以這兩種結構就是物件和陣列兩種結構,通過這兩種結構可以表示各種複雜的結構。
(1)、物件:物件在js中表示為“{}”括起來的內容,資料結構為 {key:value,key:value,...}的鍵值對的結構,在面向物件的語言中,key為物件的屬性,value為對應的屬性值,所以很容易理解,取值方法為 物件.key 獲取屬性值,這個屬性值的型別可以是 數字、字串、陣列、物件幾種。
(2)、陣列:陣列在js中是中括號“[]”括起來的內容,資料結構為 ["java","javascript","vb",...],取值方式和所有語言中一樣,使用索引獲取,欄位值的型別可以是數字、字串、陣列、物件幾種。
經過物件、陣列2種結構就可以組合成複雜的資料結構了。
14. js延遲載入的方式有哪些?
參考答案
1. defer和async
2. 動態建立DOM方式(建立script,插入到DOM中,載入完畢後callBack)
3. 按需非同步載入js
15. 說說你對延遲物件deferred的理解?
參考答案
deferred物件是從jQuery 1.5.0版本開始引入的一個新功能。
a、什麼是deferred物件
開發網站的過程中,我們經常遇到某些耗時很長的javascript操作。其中,既有非同步的操作(比如ajax讀取伺服器資料),也有同步的操作(比如遍歷一個大型陣列),它們都不是立即能得到結果的。
通常的做法是,為它們指定回撥函式(callback)。即事先規定,一旦它們執行結束,應該呼叫哪些函式。
但是,在回撥函式方面,jQuery的功能非常弱。為了改變這一點,jQuery開發團隊就設計了deferred物件。
簡單說,deferred物件就是jQuery的回撥函式解決方案。在英語中,defer的意思是"延遲",所以deferred物件的含義就是"延遲"到未來某個點再執行。
它解決了如何處理耗時操作的問題,對那些操作提供了更好的控制,以及統一的程式設計介面。
b、它的主要功能,可以歸結為四點:
(1)、實現鏈式操作
(2)、指定同一操作的多個回撥函式
(3)、為多個操作指定回撥函式
(4)、普通操作的回撥函式介面
16. 什麼是跨域,如何實現跨域訪問?
參考答案
跨域是指不同域名之間相互訪問。
JavaScript同源策略的限制,A域名下的JavaScript無法操作B或是C域名下的物件實現:
(1)、JSONP跨域:利用script指令碼允許引用不同域下的js實現的,將回調方法帶入伺服器,返回結果時回撥。
(2)、跨域資源共享(CORS)
跨域資源共享(CORS)是一種網路瀏覽器的技術規範,它為Web伺服器定義了一種方式,允許網頁從不同的域訪問其資源。
CORS與JSONP相比:
a、 JSONP只能實現GET請求,而CORS支援所有型別的HTTP請求。
b、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得資料,比起JSONP有更好的錯誤處理。
c、 JSONP主要被老的瀏覽器支援,它們往往不支援CORS,而絕大多數現代瀏覽器都已經支援了CORS。
17. 為什麼要使用模板引擎?
參考答案
a、模板引擎(這裡特指用於Web開發的模板引擎)是為了使使用者介面與業務資料(內容)分離而產生的,它可以生成特定格式的文件,用於網站的模板引擎就會生成一個標準的HTML文件。
b、在一些示例中javascript有大量的html字串,html中有一些像onclick樣的javascript,這樣javascript中有html,html中有javascript,程式碼的偶合度很高,不便於修改與維護,使用模板引擎可以解決問題。
18. documen.write和 innerHTML 的區別
參考答案
document.write 只能重繪整個頁面
innerHTML 可以重繪頁面的一部分
19. .call() 和 .apply() 的作用?
參考答案
動態改變某個類的某個方法的執行環境
20. 哪些操作會造成記憶體洩漏?
參考答案
回答一:
(1)、IE7/8 DOM物件或者ActiveX物件迴圈引用導致記憶體洩漏
a、多個物件迴圈引用
b、迴圈引用自己
(2)、基礎的DOM洩漏
當原有的DOM被移除時,子結點引用沒有被移除則無法回收。
(3)、timer定時器洩漏
這個時候你無法回收buggyObject,解決辦法,先停止timer然後再回收
回答二:
記憶體洩漏指任何物件在您不再擁有或需要它之後仍然存在。
垃圾回收器定期掃描物件,並計算引用了每個物件的其他物件的數量。如果一個物件的引用數量為 0(沒有其他物件引用過該物件),或對該物件的惟一引用是迴圈的,那麼該物件的記憶體即可回收。
setTimeout 的第一個引數使用字串而非函式的話,會引發記憶體洩漏。
閉包、控制檯日誌、迴圈(在兩個物件彼此引用且彼此保留時,就會產生一個迴圈)也會引發記憶體洩漏問題。
21. 如何判斷當前指令碼執行在瀏覽器還是node環境中?
參考答案
通過判斷 Global 物件是否為window,如果不為window,當前指令碼沒有執行在瀏覽器中。即在node中的全域性變數是global ,瀏覽器的全域性變數是window。 可以通過該全域性變數是否定義來判斷宿主環境
22. 對前端介面工程師這個職位是怎麼樣理解的?它的前景會怎麼樣?
參考答案
前端是最貼近使用者的程式設計師,比後端、資料庫、產品經理、運營、安全都近。
1. 實現介面互動
2. 提升使用者體驗
3. 有了Node.js,前端可以實現服務端的一些事情
前景:
1. 前端是最貼近使用者的程式設計師,前端的能力就是能讓產品從 90分進化到 100 分,甚至更好
2. 參與專案,快速高質量完成實現效果圖,精確到1px;
3. 與團隊成員,UI設計,產品經理的溝通;
4. 做好的頁面結構,頁面重構和使用者體驗;
5. 處理hack,相容、寫出優美的程式碼格式;
6. 針對伺服器的優化、擁抱最新前端技術。
23. http狀態碼有那些?分別代表是什麼意思?
參考答案
100 Continue 繼續,一般在傳送post請求時,已傳送了http header之後服務端將返回此資訊,表示確認,之後傳送具體引數資訊
200 OK 正常返回資訊
201 Created 請求成功並且伺服器建立了新的資源
202 Accepted 伺服器已接受請求,但尚未處理
301 Moved Permanently 請求的網頁已永久移動到新位置
302 Found 臨時性重定向
303 See Other 臨時性重定向,且總是使用 GET 請求新的 URI
304 Not Modified 自從上次請求後,請求的網頁未修改過
400 Bad Request 伺服器無法理解請求的格式,客戶端不應當嘗試再次使用相同的內容發起請求
401 Unauthorized 請求未授權
403 Forbidden 禁止訪問
404 Not Found 找不到如何與 URI 相匹配的資源
500 Internal Server Error 最常見的伺服器端錯誤
503 Service Unavailable 伺服器端暫時無法處理請求(可能是過載或維護)
24. 一個頁面從輸入 URL 到頁面載入顯示完成,這個過程中都發生了什麼?
參考答案
分為4個步驟:
1. 當傳送一個 URL 請求時,不管這個 URL 是 Web 頁面的 URL 還是 Web 頁面上每個資源的 URL,瀏覽器都會開啟一個執行緒來處理這個請求,同時在遠端 DNS 伺服器上啟動一個 DNS 查詢。這能使瀏覽器獲得請求對應的 IP 地址。
2. 瀏覽器與遠端 Web 伺服器通過 TCP 三次握手協商來建立一個 TCP/IP 連線。該握手包括一個同步報文,一個同步-應答報文和一個應答報文,這三個報文在 瀏覽器和伺服器之間傳遞。該握手首先由客戶端嘗試建立起通訊,而後伺服器應答並接受客戶端的請求,最後由客戶端發出該請求已經被接受的報文。
3. 一旦 TCP/IP 連線建立,瀏覽器會通過該連線向遠端伺服器傳送 HTTP 的 GET 請求。遠端伺服器找到資源並使用 HTTP 響應返回該資源,值為 200 的 HTTP 響應狀態表示一個正確的響應。
4. 此時,Web 伺服器提供資源服務,客戶端開始下載資源。
請求返回後,便進入了我們關注的前端模組
簡單來說,瀏覽器會解析 HTML 生成 DOM Tree,其次會根據 CSS 生成 CSS Rule Tree,而 javascript 又可以根據 DOM API 操作 DOM
25. 平時如何管理你的專案?
參考答案
1. 先期團隊必須確定好全域性樣式(globe.css),編碼模式(utf-8) 等
2. 編寫習慣必須一致(例如都是採用繼承式的寫法,單樣式都寫成一行)
3. 標註樣式編寫人,各模組都及時標註(標註關鍵樣式呼叫的地方)
4. 頁面進行標註(例如 頁面 模組 開始和結束)
5. CSS 跟 HTML 分資料夾並行存放,命名都得統一(例如 style.css)
6. JS 分資料夾存放,命名以該 JS 功能為準的英文翻譯
7. 圖片採用整合的 images.png png8 格式檔案使用 儘量整合在一起使用方便將來的管理
26. 說說最近最流行的一些東西吧?常去的哪些網站?
參考答案
最流行的一些東西:
1. Node.js
2. Mongodb
3. npm
4. MVVM
5. MEAN
6. three.js
7. React
常去的網站:
1. 牛客網
2. Github
3. CSDN
27. javascript物件的幾種建立方式
(1) var obj = new Object();
(1) 工廠模式function Parent(){ var Child = new Object(); Child.name="欲淚成雪"; Child.age="20"; return Child; }; var x = Parent();
引用該物件的時候,這裡使用的是 var x = Parent()而不是 var x = new Parent();因為後者會可能出現很多問題(前者也成為工廠經典方式,後者稱之為混合工廠方式),不推薦使用new的方式使用該物件
(2)建構函式方式function Parent(){ this.name="欲淚成雪"; this.age="20"; }; var x =new Parent();
(3) 原型模式
function Parent(){ }; Parent.prototype.name="欲淚成雪"; Parent.prototype.age="20"; var x =new Parent();
(4)混合的建構函式,原型方式(推薦)
function Parent(){ this.name="欲淚成雪"; this.age=22; }; Parent.prototype.lev=function(){ return this.name; }; var x =new Parent();
(5)動態原型方式
function Parent(){ this.name="欲淚成雪"; this.age=22; ; if(typeof Parent._lev=="undefined"){ Parent.prototype.lev=function(){ return this.name; } Parent._lev=true; } }; var x =new Parent();
28. javascript繼承的 6 種方法
參考答案
1. 原型鏈繼承
2. 借用建構函式繼承
3. 組合繼承(原型+借用構造)
4. 原型式繼承
5. 寄生式繼承
6. 寄生組合式繼承
29. Ajax 是什麼?Ajax 的互動模型?同步和非同步的區別?如何解決跨域問題?
參考答案
Ajax 是什麼:
AJAX全稱為“Asynchronous JavaScript And XML”(非同步JavaScript和XML) 是指一種建立互動式網頁應用的開發技術、改善使用者體驗,實現無重新整理效果。
Ajax 的最大的特點:
1. Ajax可以實現動態不重新整理(區域性重新整理)
2. readyState 屬性狀態有5個可取值: 0 = 未初始化,1 = 啟動, 2 = 傳送,3 = 接收,4 = 完成
Ajax 同步和非同步的區別:
1. 同步:提交請求 -> 等待伺服器處理 -> 處理完畢返回,這個期間客戶端瀏覽器不能幹任何事
2. 非同步:請求通過事件觸發 -> 伺服器處理(這是瀏覽器仍然可以作其他事情)-> 處理完畢
ajax.open方法中,第3個引數是設同步或者非同步。
優點:
1. 通過非同步模式,提升了使用者體驗
2. 優化了瀏覽器和伺服器之間的傳輸,減少不必要的資料往返,減少了頻寬佔用
3. Ajax 在客戶端執行,承擔了一部分本來由伺服器承擔的工作,減少了大使用者量下的伺服器負載。缺點:
a、瀏覽器對XMLHttpRequest物件的支援度不足,幾乎所有瀏覽器現在都支援
b、破壞瀏覽器“前進”、“後退”按鈕的正常功能,可以通過簡單的外掛彌補
c、對搜尋引擎的支援不足
解決跨域問題:
1. jsonp
2. iframe
3. window.name、window.postMessage
4. 伺服器上設定代理頁面
30. ajax 的過程是怎樣的
參考答案
1. 建立XMLHttpRequest物件,也就是建立一個非同步呼叫物件
2. 建立一個新的HTTP請求,並指定該HTTP請求的方法、URL及驗證資訊
3. 設定響應HTTP請求狀態變化的函式
4. 傳送HTTP請求
5. 獲取非同步呼叫返回的資料
6. 使用JavaScript和DOM實現區域性重新整理
31. 非同步載入和延遲載入
參考答案
1. 非同步載入的方案: 動態插入 script 標籤
2. 通過 ajax 去獲取 js 程式碼,然後通過 eval 執行
3. script 標籤上新增 defer 或者 async 屬性
4. 建立並插入 iframe,讓它非同步執行 js
5. 延遲載入:有些 js 程式碼並不是頁面初始化的時候就立刻需要的,而稍後的某些情況才需要的
32. 前端的安全問題?
參考答案
1. XSS
2. sql注入
3. CSRF:是跨站請求偽造,很明顯根據剛剛的解釋,他的核心也就是請求偽造,通過偽造身份提交POST和GET請求來進行跨域的攻擊
完成CSRF需要兩個步驟:
1. 登陸受信任的網站A,在本地生成 COOKIE
2. 在不登出A的情況下,或者本地 COOKIE 沒有過期的情況下,訪問危險網站B。
33. ie 各版本和 chrome 可以並行下載多少個資源
參考答案
1. IE6 2 個併發
2. iE7 升級之後的 6 個併發,之後版本也是 6 個
3. Firefox,chrome 也是6個
34. grunt, YUI compressor 和 google clojure用來進行程式碼壓縮的用法。
參考答案
grunt:
UglifyJS 是基於 NodeJS 的 Javascript 語法解析/壓縮/格式化工具
官網:http://lisperator.net/uglifyjs/ 或者 https://github.com/mishoo/UglifyJS2
安裝:$ npm install uglify-js -g
使用方法見官網 demo
YUI compressor:
YUI Compressor 是一個用來壓縮 JS 和 CSS 檔案的工具,採用Java開發。
使用方法:// 壓縮JS java -jar yuicompressor-2.4.2.jar --type js --charset utf-8 -v src.js > packed.js // 壓縮CSS java -jar yuicompressor-2.4.2.jar --type css --charset utf-8 -v src.css > packed.css
Google Closure Compiler:
官網:https://developers.google.com/closure/compiler/
使用方法:
1. 在命令列下使用一個google編譯好的java程式
2. 使用google提供的線上服務
3. 使用google提供的RESTful API
35. Flash、Ajax各自的優缺點,在使用中如何取捨?
參考答案
Ajax的優勢:
(1)、可搜尋性
普通的文字網頁會更有利於SEO。文字內容是搜尋引擎容易檢索的,而繁瑣的swf位元組碼卻是搜尋引擎不願觸及的。雖然Google等一些大型的搜尋引擎可以檢索SWF內部的內容,但是仍然有很多麻煩存在。
(2)、開放性
Flash常年以來被Macromedia看的很死。包括Flex、FMS等輔佐技術一直都需要昂貴的安裝、維護費用。而JS則沒有這樣的麻煩。沒有人願意承擔法律和版權的風險。
費用
Flash開發是很昂貴的,因為FlashIDE等環境都是要收費的.而Ajax則不同.雖然有一些便宜的生成swf的工具,但是他們的工能實在無法滿足複雜需求。
(3)、易用性
Ajax程式有更好的易用性。由於中間有一層Flashplayer代理層,因此許多輔助功能無法被Flash靈活利用。而且Flash在一些方面有著不好的口碑。比如彈出廣告、比如惡意程式碼。
(awflasher.com個人認為這八成是亂上xx網站造成的)
(4)、易於開發
人們開發複雜的Ajax和Flash應用程式時,都會藉助一些高階的開發工具。普遍來說,Ajax的開發包比Flash簡便、容易。
Flash的優勢:
(1)、多媒體處理
Flash在音訊、視訊等多媒體領域相比HTML有絕對的優勢。現在幾乎所有的網站都包含有Flash內容。
(2)、相容性
相容性好:由於通過了唯一的FlashPlayer“代理”。人們不必像除錯JS那樣,在不同的瀏覽器中除錯程式。
(3)、向量圖型
這是Flash最大的優勢,同樣處在這一領域的SVG、Canvas element以及Direct完全不能與Flash相比。
(4)、客戶端資源排程
Flash能夠更容易的呼叫瀏覽器以外的外部資源。比如攝像頭、麥克風等。然而這是普通的HTML無法完成的。但是這也許是一個缺點(為什麼呢?)
Ajax的劣勢:
(1)、它可能破壞瀏覽器的後退功能
(2)、使用動態頁面更新使得使用者難於將某個特定的狀態儲存到收藏夾中 ,不過這些都有相關方法解決。
Flash的劣勢:
(1)、二進位制格式
(2)、格式私有
(3)、flash 檔案經常會很大,使用者第一次使用的時候需要忍耐較長的等待時間
(4)/效能問題
ajax與flash各有利弊,到底哪個好,這取決於你的需求
36. 請解釋一下 JavaScript 的同源策略。
參考答案
概念:
同源策略是客戶端指令碼(尤其是Javascript)的重要的安全度量標準。它最早出自Netscape Navigator2.0,其目的是防止某個文件或指令碼從多個不同源裝載。
這裡的同源策略指的是:協議,域名,埠相同,同源策略是一種安全協議,指一段指令碼只能讀取來自同一來源的視窗和文件的屬性。
為什麼要有同源限制:
我們舉例說明:比如一個黑客程式,他利用Iframe把真正的銀行登入頁面嵌到他的頁面上,當你使用真實的使用者名稱,密碼登入時,他的頁面就可以通過Javascript讀取到你的表單中input中的內容,這樣使用者名稱,密碼就輕鬆到手了。
37. 什麼是 "use strict"; ? 使用它的好處和壞處分別是什麼?
參考答案
ECMAscript 5添加了第二種執行模式:"嚴格模式"(strict mode)。顧名思義,這種模式使得Javascript在更嚴格的條件下執行。
設立"嚴格模式"的目的,主要有以下幾個:
1. 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
2. 消除程式碼執行的一些不安全之處,保證程式碼執行的安全;
3. 提高編譯器效率,增加執行速度;
4. 為未來新版本的Javascript做好鋪墊。
注:經過測試 IE6,7,8,9 均不支援嚴格模式。
缺點:
現在網站的 JS 都會進行壓縮,一些檔案用了嚴格模式,而另一些沒有。這時這些本來是嚴格模式的檔案,被 merge 後,這個串就到了檔案的中間,不僅沒有指示嚴格模式,反而在壓縮後浪費了位元組。
38. GET和POST的區別,何時使用POST?
參考答案
(1)、get 是從伺服器上獲取資料,post 是向伺服器傳送資料。 get 請求返回 request - URI 所指出的任意資訊。
Post 請求用來發送電子郵件、新聞或傳送能由互動使用者填寫的表格。這是唯一需要在請求中傳送body的請求。使用Post請求時需要在報文首部 Content - Length 欄位中指出body的長度。
(2)、get 是把引數資料佇列加到提交表單的ACTION屬性所指的URL中,值和表單內各個欄位一一對應,在URL中可以看到。post是通過HTTP post機制,將表單內各個欄位與其內容放置在HTML HEADER內一起傳送到ACTION屬性所指的URL地址,使用者看不到這個過程。
(3)、對於 get 方式,伺服器端用Request.QueryString獲取變數的值,對於 post 方式,伺服器端用Request.Form獲取提交的資料。
(4)、get 傳送的資料量較小,不能大於2KB。post 傳送的資料量較大,一般被預設為不受限制。但理論上,IIS4中最大量為80KB,IIS5中為100KB。 用IIS過濾器的只接受get引數,所以一般大型搜尋引擎都是用get方式。
(5)get安全性非常低,post 安全性相對較高。如果這些資料是中文資料而且是
非敏感資料,那麼使用get;如果使用者輸入的資料不是中文字元而且包含敏感資料,那麼還是使用 post 為好。
39. 哪些地方會出現css阻塞,哪些地方會出現js阻塞?
參考答案
js的阻塞特性:所有瀏覽器在下載JS的時候,會阻止一切其他活動,比如其他資源的下載,內容的呈現等等。直到JS下載、解析、執行完畢後才開始繼續並行下載其他資源並呈現內容。為了提高使用者體驗,新一代瀏覽器都支援並行下載JS,但是JS下載仍然會阻塞其它資源的下載(例如.圖片,css檔案等)。
由於瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以就會阻塞其他的下載和呈現。
嵌入JS會阻塞所有內容的呈現,而外部JS只會阻塞其後內容的顯示,2種方式都會阻塞其後資源的下載。也就是說外部樣式不會阻塞外部指令碼的載入,但會阻塞外部指令碼的執行。
CSS怎麼會阻塞載入?CSS本來是可以並行下載的,在什麼情況下會出現阻塞載入了(在測試觀察中,IE6下CSS都是阻塞載入)
當CSS後面跟著嵌入的JS的時候,該CSS就會出現阻塞後面資源下載的情況。而當把嵌入JS放到CSS前面,就不會出現阻塞的情況了。
根本原因:因為瀏覽器會維持html中css和js的順序,樣式表必須在嵌入的JS執行前先載入、解析完。而嵌入的JS會阻塞後面的資源載入,所以就會出現上面CSS阻塞下載的情況。
JS應該放在什麼位置?
(1)、放在底部,雖然放在底部照樣會阻塞所有呈現,但不會阻塞資源下載。
(2)、如果嵌入JS放在head中,請把嵌入JS放在CSS頭部。
(3)、使用defer(只支援IE)
(4)、不要在嵌入的JS中呼叫執行時間較長的函式,如果一定要用,可以用`setTimeout`來呼叫
Javascript無阻塞載入具體方式
將指令碼放在底部。<link>還是放在head中,用以保證在js載入前,能加載出正常顯示的頁面。<script>標籤放在</body>前。
成組指令碼:由於每個<script>標籤下載時阻塞頁面解析過程,所以限制頁面的<script>總數也可以改善效能。適用於內聯指令碼和外部指令碼。
非阻塞指令碼:等頁面完成載入後,再載入js程式碼。也就是,在window.onload事件發出後開始下載程式碼。
(1)defer屬性:支援IE4和fierfox3.5更高版本瀏覽器
(2)動態指令碼元素:文件物件模型(DOM)允許你使用js動態建立HTML的幾乎全部文件內容。程式碼如下:<script> var script=document.createElement("script"); script.type="text/javascript"; script.src="file.js"; document.getElementsByTagName("head")[0].appendChild(script); </script>
此技術的重點在於:無論在何處啟動下載,檔案額下載和執行都不會阻塞其他頁面處理過程,即使在head裡(除了用於下載檔案的 http 連結)。
40. eval是做什麼的?
參考答案
1. 它的功能是把對應的字串解析成JS程式碼並執行
2. 應該避免使用eval,不安全,非常耗效能(2次,一次解析成js語句,一次執行)
41. 寫一個通用的事件偵聽器函式
參考答案
// event(事件)工具集,來源:github.com/markyun
markyun.Event = { // 頁面載入完成後
readyEvent: function(fn) {
if (fn == null) { fn = document;
}
var oldonload = window.onload;
if (typeof window.onload != 'function') { window.onload = fn;
} else { window.onload = function() { oldonload(); fn();
};
}
},
// 視能力分別使用dom0||dom2||IE方式 來繫結事件
// 引數: 操作的元素,事件名稱 ,事件處理程式
addEvent: function(element, type, handler) {
if (element.addEventListener) { //事件型別、需要執行的函式、是否捕捉
element.addEventListener(type, handler, false);
} else if (element.attachEvent) { element.attachEvent('on' + type,
function() { handler.call(element);
});
} else { element['on' + type] = handler;
}
},
// 移除事件
removeEvent: function(element, type, handler) {
if (element.removeEnentListener) { element.removeEnentListener(type, handler, false);
} else if (element.detachEvent) { element.detachEvent('on' + type, handler);
} else { element['on' + type] = null;
}
},
// 阻止事件 (主要是事件冒泡,因為IE不支援事件捕獲)
stopPropagation: function(ev) {
if (ev.stopPropagation) { ev.stopPropagation();
} else { ev.cancelBubble = true;
}
},
// 取消事件的預設行為
preventDefault: function(event) {
if (event.preventDefault) { event.preventDefault();
} else { event.returnValue = false;
}
},
// 獲取事件目標
getTarget: function(event) {
return event.target || event.srcElement;
},
// 獲取event物件的引用,取到事件的所有資訊,確保隨時能使用event;
getEvent: function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) { ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
} c = c.caller;
}
}
return ev;
}
};
42. JavaScript 原型,原型鏈 ? 有什麼特點?
參考答案
1. 原型物件也是普通的物件,是物件一個自帶隱式的 __proto__ 屬性,原型也有可能有自己的原型,如果一個原型物件的原型不為 null 的話,我們就稱之為原型鏈.
2. 原型鏈是由一些用來繼承和共享屬性的物件組成的(有限的)物件鏈。每個建構函式都有一個原型物件 ,原型物件都包含一個指向建構函式的指標 ,而例項都包含一個指向原型物件的內部指標。那麼,假如我們讓原型物件等於另一個型別的例項,顯然,此時的原型物件將包含一個指向另一個原型的指標,相應地 ,另一個原型中也包含著一個指向另一個建構函式的指標。假如另一個原型又是另一個型別的例項,那麼上述關係依然成立 ,如此層層遞進 ,就構成了例項與原型的鏈條。這就是所謂原型鏈的基本概念。
43. 怎麼重構頁面?
參考答案
1. 編寫 CSS
2. 讓頁面結構更合理化,提升使用者體驗
3. 實現良好的頁面效果和提升效能
44. 事件、IE與火狐的事件機制有什麼區別? 如何阻止冒泡?如何阻止預設行為?
參考答案
1. 事件:
我們在網頁中的某個操作(有的操作對應多個事件)。例如:當我們點選一個按鈕就會產生一個事件。是可以被 JavaScript 偵測到的行為
2. 事件處理機制:
IE是事件冒泡、firefox同時支援兩種事件模型,也就是:捕獲型事件和冒泡型事件
事件冒泡:由文件內巢狀最深的節點開始,向上傳播直到最外層的節點。
事件捕獲:從最外層的節點,向內捕獲到最深的節點。
3. 阻止冒泡:
非IE:event.stopPropagation(); 只有當cancelable屬性設定為true時才能使用
IE:cancelBubble = true;
4. 阻止預設行為:
非IE:preventDefault()方法
IE:returnValue = false
45. js物件的深度克隆程式碼實現
參考答案
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = []; // 建立一個空的陣列
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
} else if (Obj instanceof Object){
buf = {}; // 建立一個空物件
for (var k in Obj) { // 為這個物件新增新的屬性
buf[k] = clone(Obj[k]);
}
return buf;
}else{
return Obj;
}
}
46. 事件委託機制?
參考答案
事件委託就是利用事件冒泡,只指定一個事件處理程式,就可以管理某一型別的所有事件。比如一個DOM節點,div>ul>li*n,我們需要給每個li繫結一個click點選事件,傳統的做法的做法就是獲取每一個li,分別指定事件處理程式;但這樣做的結果,使得DOM的操作過於頻繁,效能降低。這時,事件委託就可以去解決這個問題:給ul繫結一個事件處理程式,當li被點選時,由於冒泡原理,事件就會冒泡到ul上,因為ul上有onclick事件處理程式,所以單擊事件就會被這個函式處理。如果需要每個li做不同的操作,可以給每個li繫結一個id屬性,通過event物件的target屬性,使用switch...case語句,就可以對不同的li做不同的操作。
47. 如何獲取UA
參考答案
<script>
function whatBrowser() {
document.Browser.Name.value=navigator.appName;
document.Browser.Version.value=navigator.appVersion;
document.Browser.Code.value=navigator.appCodeName;
document.Browser.Agent.value=navigator.userAgent;
}
</script>
48. 用JavaScript指令碼為Array物件新增一個去除重複項的方法。
參考答案
Array.prototype.uniq = function () {
// 長度只有1,直接返回當前的拷貝
if (this.length <= 1) {
return this.slice(0);
}
var aResult = [];
for (var i = 0, l = this.length; i < l; i++) {
if (!_fExist(aResult, this[i])) {
aResult.push(this[i]);
}
}
return aResult;
// 判斷是否重複
function _fExist(aTmp, o) {
if (aTmp.length === 0) {
return false;
}
var tmp;
for (var i = 0, l = aTmp.length; i < l; i++) {
tmp = aTmp[i];
if (tmp === o) {
return true;
}
// NaN 需要特殊處理
if (!o && !tmp && tmp !== undefined && o !== undefined && isNaN(tmp) && isNaN(o)) {
return true;
}
}
return false;
}
}
49. cache-control
參考答案
網頁的快取是由HTTP訊息頭中的“Cache-control”來控制的,常見的取值有private、no-cache、max-age、must-revalidate等,預設為private。
Expires 頭部欄位提供一個日期和時間,響應在該日期和時間後被認為失效。允許客戶端在這個時間之前不去檢查(發請求),等同max-age的效果。但是如果同時存在,則被Cache-Control的max-age覆蓋。
Expires = "Expires" ":" HTTP-date
例如:
Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)
如果把它設定為-1,則表示立即過期
Expires 和 max-age 都可以用來指定文件的過期時間,但是二者有一些細微差別
1. Expires在HTTP/1.0中已經定義,Cache-Control:max-age在HTTP/1.1中才有定義,為了向下相容,僅使用max-age不夠
2. Expires指定一個絕對的過期時間(GMT格式),這麼做會導致至少2個問題:
2.1客戶端和伺服器時間不同步導致Expires的配置出現問題。
2.2很容易在配置後忘記具體的過期時間,導致過期來臨出現浪湧現象
3. max-age 指定的是從文件被訪問後的存活時間,這個時間是個相對值(比如:3600s),相對的是文件第一次被請求時伺服器記錄的Request_time(請求時間)
4. Expires 指定的時間可以是相對檔案的最後訪問時間(Atime)或者修改時間(MTime),而max-age相對對的是文件的請求時間(Atime)
5. 如果值為 no-cache,那麼每次都會訪問伺服器。如果值為max-age,則在過期之前不會重複訪問伺服器。
50. js 操作獲取和設定 cookie
參考答案
// 建立cookie
function setCookie(name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += '; expires=' + expires;
}
if (path) {
cookieText += "; path=" + path }
if (domain) {
cookieText += '; domain=' + domain;
}
if (secure) {
cookieText += '; secure';
}
document.cookie = cookieText;
}
// 獲取cookie
function getCookie(name) {
var cookieName = encodeURIComponent(name) + '=';
var cookieStart = document.cookie.indexOf(cookieName);
var cookieValue = null;
if (cookieStart > -1) {
var cookieEnd = document.cookie.indexOf(';', cookieStart);
if (cookieEnd == -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
}
// 刪除cookie
function unsetCookie(name) {
document.cookie = name + "= ; expires=" + new Date(0);
}
51. ionic和angularjs的區別?
參考答案
a、ionic是一個用來開發混合手機應用的,開源的,免費的程式碼庫。可以優化html、css和js的效能,構建高效的應用程式,而且還可以用於構建Sass和AngularJS的優化。
b、AngularJS通過新的屬性和表示式擴充套件了HTML。AngularJS可以構建一個單一頁面應用程式(SPAs:Single Page Applications)。
c、Ionic是一個混合APP開發工具,它以AngularJS為中間指令碼工具(稱為庫,似乎又不恰當),所以,你如果要使用Ionic開發APP,就必須瞭解AngularJS。
52. 談談你對閉包的理解?
參考答案
(1)、使用閉包主要是為了設計私有的方法和變數。閉包的優點是可以避免全域性變數的汙染,缺點是閉包會常駐記憶體,會增大記憶體使用量,使用不當很容易造成記憶體洩露。
(2)、閉包有三個特性:
a、函式巢狀函式
b、函式內部可以引用外部的引數和變數
c、引數和變數不會被垃圾回收機制回收
53. 談談你This物件的理解?
參考答案
回答一:
(1)、js的this指向是不確定的,也就是說是可以動態改變的。call/apply 就是用於改變this指向的函式,這樣設計可以讓程式碼更加靈活,複用性更高
(2)、this 一般情況下,都是指向函式的擁有者。
(3)、在函式自執行裡,this 指向的是 window 物件。
擴充套件:關於this,還有一個地方比較讓人模糊的是在dom事件裡,通常有如下3種情況:
a、使用標籤屬性註冊事件,此時this指向的是window物件。
b、對於a,要讓this指向input,可以將this作為引數傳遞。
c、使用addEventListener等註冊事件。此時this也是指向 input。
回答二:
(1)、處於全域性作用域下的this:this;/*window*/ var a = {name: this}/*window*/ var b = [this];/*window*/
在全域性作用域下,this預設指向window物件。
(2)、處在函式中的this,又分為以下幾種情況:
a、一般定義的函式,然後一般的執行:var a = function(){ console.log(this); } a();/*window*/ this還是預設指向window。
b、一般定義,用new呼叫執行:
var a = function(){ console.log(this); } new a();/*新建的空物件*/
這時候讓this指向新建的空物件,我們才可以給空物件初始化自有變數
c、作為物件屬性的函式,呼叫時:var a = { f:function(){ console.log(this) } } a.f();/*a物件*/
這時候this指向呼叫f函式的a物件。
(3)、通過call()和apply()來改變this的預設引用:var b = {id: 'b'}; var a = { f:function(){ console.log(this) } } a.f.call(b);/*window*/
所有函式物件都有的call方法和apply方法,它們的用法大體相似,f.call(b);的意思是,執行f函式,並將f函式執行期活動物件裡的this指向b物件,這樣標示符解析時,this就會是b物件了。不過呼叫函式是要傳參的。所以,f.call(b, x, y); f.apply(b, [x, y]);好吧,以上就是用call方法執行f函式,與用apply方法執行f函式時傳參方式,它們之間的差異,大家一目瞭然:apply通過陣列的方式傳遞引數,call通過一個個的形參傳遞引數。
(4)、一些函式特殊執行情況this的指向問題:
a、setTimeout()和setInverval():var a = function(){ console.log(this); } setTimeout(a,0);/*window*/
setInterval()類似。
b、dom模型中觸發事件的回撥方法執行中活動物件裡的this指向該dom物件。
54. 請你解釋一下事件冒泡機制?
參考答案
a、在一個物件上觸發某類事件(比如單擊onclick事件),如果此物件定義了此事件的處理程式,那麼此事件就會呼叫這個處理程式,如果沒有定義此事件處理程式或者事件返回true,那麼這個事件會向這個物件的父級物件傳播,從裡到外,直至它被處理(父級物件所有同類事件都將被啟用),或者它到達了物件層次的最頂層,即document物件(有些瀏覽器是window)。
b、冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document物件)的順序觸發
c、js冒泡機制是指如果某元素定義了事件A,如click事件,如果觸發了事件之後,沒有阻止冒泡事件,那麼事件將向父級元素傳播,觸發父類的click函式。//阻止冒泡時間方法,相容ie(e.cancleBubble)和ff(e.stopProgation) function stopBubble(e){ var evt = e||window.event; evt.stopPropagation?evt.stopPropagation():(evt.cancelBubble=true);//阻止冒泡 evt.preventDefault
55. 請你說說split()與join() 函式的區別?
參考答案
前者是切割成陣列的形式,後者是將陣列轉換成字串
Join 函式獲取一批字串,然後用分隔符字串將它們聯接起來,從而返回一個字串。Split 函式獲取一個字串,然後在分隔符處將其斷開,從而返回一批字串。但是,這兩個函式之間的主要區別在於 Join 可以使用任何分隔符字串將多個字串連線起來,而 Split 只能使用一個字元分隔符將字串斷開。
簡單地說,如果你用split,是把一串字元(根據某個分隔符)分成若干個元素存放在一個數組裡。而Join是把陣列中的字串連成一個長串,可以大體上認為是split的逆操作。
56. 說說你對Promise的理解?
參考答案
ES6 原生提供了 Promise 物件。
所謂 Promise,就是一個物件,用來傳遞非同步操作的訊息。它代表了某個未來才會知道結果的事件(通常是一個非同步操作),並且這個事件提供統一的 API,可供進一步處理。
Promise 物件有以下兩個特點。
(1)、物件的狀態不受外界影響。Promise 物件代表一個非同步操作,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是 Promise 這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。
(2)、一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise 物件的狀態改變,只有兩種可能:從 Pending 變為 Resolved 和從 Pending 變為 Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對 Promise 物件添加回調函式,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
有了 Promise 物件,就可以將非同步操作以同步操作的流程表達出來,避免了層層巢狀的回撥函式。此外,Promise 物件提供統一的介面,使得控制非同步操作更加容易。
Promise 也有一些缺點。首先,無法取消 Promise,一旦新建它就會立即執行,無法中途取消。其次,如果不設定回撥函式,Promise 內部丟擲的錯誤,不會反應到外部。第三,當處於 Pending 狀態時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。
57. 談談你對Javascript垃圾回收機制的理解?
參考答案
(1)、標記清除(mark and sweep)
這是`JavaScript`最常見的垃圾回收方式,當變數進入執行環境的時候,比如函式中宣告一個變數,垃圾回收器將其標記為“進入環境”,當變數離開環境的時候(函式執行結束)將其標記為“離開環境”。
垃圾回收器會在執行的時候給儲存在記憶體中的所有變數加上標記,然後去掉環境中的變數以及被環境中變數所引用的變數(閉包),在這些完成之後仍存在標記的就是要刪除的變量了
(2)、引用計數(reference counting)
在低版本`IE`中經常會出現記憶體洩露,很多時候就是因為其採用引用計數方式進行垃圾回收。引用計數的策略是跟蹤記錄每個值被使用的次數,當聲明瞭一個變數並將一個引用型別賦值給該變數的時候這個值的引用次數就加1,如果該變數的值變成了另外一個,則這個值得引用次數減1,當這個值的引用次數變為0的時候,說明沒有變數在使用,這個值沒法被訪問了,因此可以將其佔用的空間回收,這樣垃圾回收器會在執行的時候清理掉引用次數為0的值佔用的空間。
在IE中雖然`JavaScript`物件通過標記清除的方式進行垃圾回收,但BOM與DOM物件卻是通過引用計數回收垃圾的,也就是說只要涉及BOM及DOM就會出現迴圈引用問題。
58. 說說你對原型(prototype)理解?
參考答案
JavaScript是一種通過原型實現繼承的語言與別的高階語言是有區別的,像java,C#是通過型別決定繼承關係的,JavaScript是的動態的弱型別語言,總之可以認為JavaScript中所有都是物件,在JavaScript中,原型也是一個物件,通過原型可以實現物件的屬性繼承,JavaScript的物件中都包含了一個" prototype"內部屬性,這個屬性所對應的就是該物件的原型。
"prototype"作為物件的內部屬性,是不能被直接訪問的。所以為了方便檢視一個物件的原型,Firefox和Chrome核心的JavaScript引擎中提供了"__proto__"這個非標準的訪問器(ECMA新標準中引入了標準物件原型訪問器"Object.getPrototype(object)")。
原型的主要作用就是為了實現繼承與擴充套件物件。
59. typeof與instanceof的區別是什麼?
參考答案
在 JavaScri