時間飛逝,轉眼間從離開百度到近3年了。工做也發生了巨大變化,從之前的企業項目開發到如今在學校日復一日地爲學生授課,但不管對着計算機編程,仍是爲學生講述前端知識,都十分讓我享受。c++
每到畢業季,看着本身帶出的學生找到理想的工做,心中亦是十分欣慰。學生求職中,常常會問我一些面試中的問題,每次耐心地幫他們解答,對他們幫助很大。程序員
臨近畢業的學生不少恐懼面試,面試
經過這些活動我認識到,不管是在面試中,仍是工做中,經過學習瞭解確實能夠避免少踩一些坑,少走一些彎路,因而我將培訓學校內部用的前端面試知識,整理成一本書。編程
但願可以與更多的讀者分享愛創課堂的知識;但願《前端程序員面試祕籍》可以幫助那些正在找工做的人順利找到工做;也但願這本書可以幫助那些在工做中遇到問題而躊躇不前的人順利解決問題;同時也但願這本書可以幫助那些學習前端、指望瞭解前端更多知識的人。數組
1.JavaScript有哪些垃圾回收機制?瀏覽器
答:有如下垃圾回收機制。安全
- 標記清除(mark and sweep)
這是JavaScript最多見的垃圾回收方式。當變量進入執行環境的時候,好比在函數中聲明一個變量,垃圾回收器將其標記爲「進入環境」。當變量離開環境的時候(函數執行結束),將其標記爲「離開環境」。服務器
垃圾回收器會在運行的時候給存儲在內存中的全部變量加上標記,而後去掉環境中的變量,以及被環境中變量所引用的變量(閉包)的標記。在完成這些以後仍然存在的標記就是要刪除的變量。微信
- 引用計數(reference counting)
在低版本的IE中常常會發生內存泄漏,不少時候就是由於它採用引用計數的方式進行垃圾回收。
引用計數的策略是跟蹤記錄每一個值被使用的次數。當聲明瞭一個變量並將一個引用類型賦值給該變量的時候,這個值的引用次數就加1。若是該變量的值變成了另一個,則這個值的引用次數減1。當這個值的引用次數變爲0的時候,說明沒有變量在使用,這個值無法被訪問。
所以,能夠將它佔用的空間回收,這樣垃圾回收器會在運行的時候清理引用次數爲0的值佔用的空間。
在IE中雖然JavaScript對象經過標記清除的方式進行垃圾回收,可是BOM與DOM對象是用引用計數的方式回收垃圾的。也就是說,只要涉及BOM和DOM,就會出現循環引用問題。
2.列舉幾種類型的DOM節點
答:有如下幾類DOM節點。
- 整個文檔是一個文檔節點。
- 每一個HTML標籤是一個元素節點。
- 每個HTML屬性是一個屬性節點。
- 包含在HTML元素中的文本是文本節點。
3.談談script標籤中defer和async屬性的區別。
答:區別以下。
(1)defer屬性規定是否延遲執行腳本,直到頁面加載爲止。async屬性規定腳本一旦可用,就異步執行。
(2)defer並行加載JavaScript文件,會按照頁面上script標籤的順序執行。async並行加載JavaScript文件,下載完成當即執行,不會按照頁面上script標籤的順序執行。
4.說說你對閉包的理解。
答:使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染;缺點是閉包會常駐內存,增長內存使用量,使用不當很容易形成內存泄漏。在JavaScript中,函數即閉包,只有函數纔會產生做用域。
閉包有3個特性。
(1)函數嵌套函數。
(2)在函數內部能夠引用外部的參數和變量。
(3)參數和變量不會以垃圾回收機制回收。
5.解釋一下unshift()方法。
答:該方法在數組啓動時起做用,與push()不一樣。它將參數成員添加到數組的答頂部。下面給出一段示例代碼。
var name=["john"] name.unshift("charlie"); name.unshift("joseph","Jane"); console.log(name);
輸出以下所示。
[" joseph "," Jane ", " charlie ", " john "]
6.encodeURI()和decodeURI()的做用是什麼?
答:encodeURl()用於將URL轉換爲十六進制編碼。而decodeURI()用於將編碼的URL轉換回正常URL。
7.爲何不建議在JavaScript中使用innerHTML?
答:經過innerHTML修改內容,每次都會刷新,所以很慢。在innerHTML中沒有驗證的機會,所以更容易在文檔中插入錯誤代碼,使網頁不穩定。
8.如何在不支持JavaScript的舊瀏覽器中隱藏JavaScript代碼?
答:在標籤以前添加「// -->」,代碼中沒有引號。
舊瀏覽器如今將JavaScript代碼視爲一個長的HTML註釋,而支持JavaScript的瀏覽器則將「」做爲一行註釋。
9.在DOM操做中怎樣建立、添加、移除、替換、插入和查找節點?
答:具體方法以下。
(1)經過如下代碼建立新節點。
createDocumentFragment() //建立一個DOM片斷 createElement() //建立一個具體的元素 createTextNode() //建立一個文本節點
(2)經過如下代碼添加、移除、替換、插入節點。
appendChild() removeChild() replaceChild() insertBefore() //並無insertAfter()
(3)經過如下代碼查找節點。
getElementsByTagName() //經過標籤名稱查找節點 getElementsByName() //經過元素的name屬性的值查找節點(IE容錯能力較強,會獲得一個數 //組,其中包括id等於name值的節點) getElementById() //經過元素Id查找節點,具備惟一性
10.如何實現瀏覽器內多個標籤頁之間的通訊?
答:調用localstorge、cookie等數據存儲通訊方式。
11.null和undefined的區別是什麼?
答:null是一個表示「無」的對象,轉爲數值時爲0;undefined是一個表示「無」的原始值,轉爲數值時爲NaN。
當聲明的變量還未初始化時,變量的默認值爲undefined。
null用來表示還沒有存在的對象,經常使用來表示函數企圖返回一個不存在的對象。
undefined表示「缺乏值」,即此處應該有一個值,可是尚未定義,典型用法是以下。
(1)若是變量聲明瞭,但沒有賦值,它就等於undefined。
(2)當調用函數時,若是沒有提供應該提供的參數,該參數就等於undefined。
(3)若是對象沒有賦值,該屬性的值爲undefined。
(4)當函數沒有返回值時,默認返回undefined。
null表示「沒有對象」,即此處不該該有值,典型用法是以下。
(1)做爲函數的參數,表示該函數的參數不是對象。
(2)做爲對象原型鏈的終點。
12.new操做符的做用是什麼?
答:做用以下。
(1)建立一個空對象。
(2)由this變量引用該對象。
(3)該對象繼承該函數的原型(更改原型鏈的指向)。
(4)把屬性和方法加入到this引用的對象中。
(5)新建立的對象由this引用,最後隱式地返回this,過程以下。
var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj);
13.JavaScript延遲加載的方式有哪些?
答:包括defer和async、動態建立DOM(建立script,插入DOM中,加載完畢後回調、按需異步載入JavaScript。
14.call()和apply() 的區別和做用是什麼?
答:做用都是在函數執行的時候,動態改變函數的運行環境(執行上下文)。
call和apply的第一個參數都是改變運行環境的對象。
區別以下。
call從第二個參數開始,每個參數會依次傳遞給調用函數;apply的第二個參數是數組,數組的每個成員會依次傳遞給調用函數。
如:
func.call(func1, var1, var2, var3)
對應的apply寫法爲:
func.apply(func1, [var1, var2, var3])
15.哪些操做會形成內存泄漏?
答:內存泄漏指再也不擁有或須要任何對象(數據)以後,它們仍然存在於內存中。
提示:垃圾回收器按期掃描對象,並計算引用了每一個對象的其餘對象的數量。若是一個對象的引用數量爲0(沒有其餘對象引用過該對象),或對該對象的惟一引用是循環的,那麼該對象佔用的內存當即被回收。
若是setTimeout 的第一個參數使用字符串而非函數,會引起內存泄漏。
閉包、控制檯日誌、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)等會造內存泄漏。
16.列舉IE與finefox的不一樣之處。
答:不一樣之處以下。
(1)IE支持currentStyle;Firefox使用getComputStyle。
(2)IE使用innerText;Firefox使用textContent。
(3)在透明度濾鏡方面,IE使用filter:alpha(opacity= num);Firefox使用-moz-opacity: num。
(4)在事件方面,IE使用attachEvent:Firefox使用addEventListener。
(5)對於鼠標位置:IE使用event.clientX;Firefox使用event.pageX。
(6)IE使用event.srcElement;Firefox使用event.target。
(7)要消除list的原點,IE中僅須使margin:0便可達到最終效果;Firetox中須要設置margin:0、padding:0和list-style:none。
(8)CSS圓角:IE7如下不支持圓角。
17.講解一下JavaScript對象的幾種建立方式。
答:有如下建立方式。
(1)Object構造函數式。
(2)對象字面量式。
(3)工廠模式。
(4)安全工廠模式。
(5)構造函數模式。
(6)原型模式。
(7)混合構造函數和原型模式。
(8)動態原型模式。
(9)寄生構造函數模式。
(10)穩妥構造函數模式。
18.如何實現異步編程?
答:具體方法以下。
方法 1,經過回調函數。優勢是簡單、容易理解和部署;缺點是不利於代碼的閱讀和維護,各個部分之間高度耦合(Coupling),流程混亂,並且每一個任務只能指定一個回調函數。
方法 2,經過事件監聽。能夠綁定多個事件,每一個事件能夠指定多個回調函數,並且能夠「去耦合」(Decoupling),有利於實現模塊化;缺點是整個程序都要變成事件驅動型,運行流程會變得很不清晰。
方法 3,採用發佈/訂閱方式。性質與「事件監聽」相似,可是明顯優於後者。
方法 4,經過Promise對象實現。Promise對象是CommonJS工做組提出的一種規範,旨在爲異步編程提供統一接口。它的思想是,每個異步任務返回一個Promise對象,該對象有一個then方法,容許指定回調函數。
19.請解釋一下JavaScript的同源策略。
答:同源策略是客戶端腳本(尤爲是JavaScript)的重要安全度量標準。它最先出自Netscape Navigator 2.0,目的是防止某個文檔或腳本從多個不一樣源裝載。
這裏的同源策略指的是協議、域名、端口相同。同源策略是一種安全協議。指一段腳本只能讀取來自同一來源的窗口和文檔的屬性。
20.爲何要有同源限制?
答:咱們舉例說明。好比一個黑客,他利用Iframe把真正的銀行登陸頁面嵌到他的頁面上,當你使用真實的用戶名、密碼登陸時,他的頁面就能夠經過JavaScript讀取到你表單上input中的內容,這樣黑客就會輕鬆獲得你的用戶名和密碼。
21.在JavaScript中,爲何說函數是第一類對象?
答:第一類函數即JavaScript中的函數。這一般意味着這些函數能夠做爲參數傳遞給其餘函數,做爲其餘函數的值返回,分配給變量,也能夠存儲在數據結構中。
22.什麼是事件? IE與Firefox的事件機制有什麼區別? 如何阻止冒泡?
答:事件是在網頁中的某個操做(有的操做對應多個事件)。例如,當單擊一個按鈕時,就會產生一個事件,它能夠被JavaScript偵測到。
在事件處理機制上,IE支持事件冒泡;Firefox同時支持兩種事件模型,也就是捕獲型事件和冒泡型事件。
阻止方法是ev.stopPropagation()。注意舊版IE中的方法ev.cancelBubble = true。
23.函數聲明與函數表達式的區別?
答:在JavaScript中,在向執行環境中加載數據時,解析器對函數聲明和函數表達式並不是是一視同仁的。解析器會首先讀取函數聲明,並使它在執行任何代碼以前可用(能夠訪問)。至於函數表達式,則必須等到解析器執行到它所在的代碼行,纔會真正解析和執行它。
24.如何刪除一個cookie?
答:爲了刪除cookie,要修改expires,代碼以下。
document.cookie = 'user=icketang;expires = ' + new Date(0)
25.編寫一個方法,求一個字符串的長度(單位是字節)。
答:假設一個英文字符佔用一字節,一箇中文字符佔用兩字節:
function GetBytes(str){ var len = str.length; var bytes = len; for(var i=0; i if (str.charCodeAt(i) > 255) bytes++; } return bytes; } alert(GetBytes("hello 愛創課堂!"));
26.對於元素,attribute和property的區別是什麼?
答:attribute是DOM元素在文檔中做爲HTML標籤擁有的屬性;property就是DOM元素在JavaScript中做爲對象擁有的屬性。
對於HTML的標準屬性來講,attribute和property是同步的,會自動更新,可是對於自定義的屬性來講,它們是不一樣步的。
27.解釋延遲腳本在JavaScript中的做用。
答:默認狀況下,在頁面加載期間,HTML代碼的解析將暫停,直到腳本中止執行。這意味着,若是服務器速度較慢或者腳本特別「沉重」,則會致使網頁延遲。在使用Deferred時,腳本會延遲執行,直到HTML解析器運行。這縮短了網頁的加載時間,而且它們的顯示速度更快。
28.什麼是閉包(closure)?
答:爲了說明閉包,建立一個閉包。
function hello() { // 函數執行完畢,變量仍然存在 var num = 100; var showResult= function() { alert(num); } num++; return showResult; } var showResult= hello(); showResult()//執行結果:彈出101
執行hello()後,hello()閉包內部的變量會存在,而閉包內部函數的內部變量不會存在,使得JavaScript的垃圾回收機制不會收回hello()佔用的資源,由於hello()中內部函數的執行須要依賴hello()中的變量。
29.如何判斷一個對象是否屬於某個類?
答:使用instanceof關鍵字,判斷一個對象是不是類的實例化對象;使用constructor屬性,判斷一個對象是不是類的構造函數。
30.JavaScript中如何使用事件處理程序?
答:事件是由用戶與頁面的交互(例如單擊連接或填寫表單)致使的操做。須要一個事件處理程序來保證全部事件的正確執行。事件處理程序是對象的額外屬性。此屬性包括事件的名稱和事件發生時採起的操做。其實作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要這裏我要推薦c++交流羣:648778840,無論你是小白仍是大牛歡迎入住,你們一塊兒交流成長。小編會在羣中不按期分享乾貨源碼,包括我精心整理的一份c++零基礎教程。歡迎各位感興趣的的小夥伴。