由於公司招人的關係,須要我出一份Web前端開發的面試題,如今招聘工做結束了,把題目記錄在這裏,供你們參考。javascript
第一部分 考察項目經歷css
這一部分的套路就是給出一個topic,讓面試者給出較爲詳細的說明,進而問一些更爲深刻的問題,達到考察的目的。html
1 自我介紹。前端
2 介紹一個印象最深的項目,使用何種技術,解決何種問題?html5
3 迄今爲止遇到的最大的一個技術挑戰?是如何解決的?java
第二部分 定點考察知識點 node
0 計算機基礎jquery
這一部分主要考察對計算機基礎知識的掌握。根據我面試的經驗,若是你所在的是一家逼格不是特別高的創業公司的話,那麼來面你這個web前端職位的人,大部分會是非計算機專業轉過來的,因此這部分他們大機率會掌握的不是很好。。因此沒有必要考察太深。git
1 簡述線程與進程的區別?github
進程由線程組成,線程是CPU調度的基本單元。
2請從插入刪除與查詢的效率角度,對鏈表與數組進行比較。
鏈表插入刪除的效率高,爲常量時間複雜度O(1),但查詢效率低,爲線性時間複雜度O(n);
數組查詢效率高,爲常量時間複雜度O(1),但插入刪除效率低,爲線性時間複雜度O(n)
3 簡述棧和隊列的區別?
棧是先入後出,隊列是先入先出。
HTML
div, span, a, strong, form, em, label, p, h1, input, ol, ul ,select, textarea, img, table
上述中哪些是inline tags(默認)? span, a(link), strong(加粗), em, label, input(輸入框), select, textarea, img
上述中哪些是block tags(默認)? div, form, p(段落), h1, ol, ul , table
塊元素與內聯元素的區別?
塊元素通常都重新行開始,它能夠容納內聯元素和其餘塊元素,常見塊元素是段落標籤'P". 若是沒有css的做用,塊元素會順序以每次另起一行的方式一直往下排。而有了css之後,咱們能夠改變這種html的默認佈局模式,把塊元素擺放到你想要 的位置上去。而不是每次都愚蠢的另起一行。
內聯元素(inline element)通常都是基於語義級(semantic)的基本元素。內聯元素只能容納文本或者其餘內聯元素,常見內聯元素 「a」。
inline-block的元素特色:將對象呈遞爲內聯對象,可是對象的內容做爲塊對象呈遞。旁邊的內聯對象會被呈遞在同一行內,容許空格。(準確地說,應用此特性的元素呈現爲內聯對象,周圍元素保持在同一行,但能夠設置寬度和高度地塊元素的屬性)
<b> 和<strong>的區別?
strong是web標準中xhtml的標籤,strong的意思是「強調」;b是html的,b的意思是bold(粗體)。爲何用strong代替b?其實這個問題不妨改問:xhtml和html有什麼不一樣,爲何要用xhtml代替html?
簡單地說:web標準主張xhtml不涉及具體的表現形式,「強調」能夠用加粗來強調,也能夠用其它方式來強調,好比下劃線,好比字體加大,好比紅色,等等,能夠經過css來改變strong的具體表現,這就是爲何b要改成strong
strong表明其中內容文字的意義。b表明其中文字的樣式是粗體。 在html規範中兩者的區別基本上看不出來。在xhtml中因爲強調「樣式與內容的分離」因此表明樣式的b被掏汰了。取而代之的是其它標籤。注意,不是strong代替了b。strong表明強調,你能夠自定義任何樣式來表明強調。只是strong的默認樣式與b相同而已。
Html的發展歷史是:Html4 xhtml html5。
H5的新特性有哪些?
用於繪畫的 canvas 元素 Websocket, <video> <audio> <header> <footer> 正則表達式
HTML5添加了許多新新的語法特徵,其中包括<video>、<audio>和<canvas>元素,同時集成了SVG內容。
1 按照下面的樣子佈局:
2 如何使用原生的create/add/remove/move/copy/search DOM中的元素?(寫出代碼)
1 var para=document.createElement("p"); // 建立 2 var element=document.getElementById("div1"); // 查找 3 getElementByTagName 4 getElementByName 5 element.appendChild(para); //追加 add 6 parent.removeChild(child); //刪除
如何選取特定的HTML元素:
1 element = document.getElementById(id);
Document 對象:每一個載入瀏覽器的 HTML 文檔都會成爲 Document 對象。Document 對象使咱們能夠從腳本中對 HTML 頁面中的全部元素進行訪問。
提示:Document 對象是 Window 對象的一部分,可經過 window.document 屬性對其進行訪問。
HTML DOM 定義了多種查找元素的方法,除了 getElementById() 以外,還有 getElementsByName() 和 getElementsByTagName()和Document.getElementByClassName();。不過,若是您須要查找文檔中的一個特定的元素,最有效的方法是 getElementById()。
如需替換 HTML DOM 中的元素,請使用 replaceChild() 方法。
cloneNode(deepBoolean)
複製並返回當前節點的複製節點,複製節點是一個孤立節點,它複製了原節點的屬性,在把這個新節點加入到document前,根據須要修改ID屬性確保其ID的惟一。
Move:
1 var divs = document.getElementsByTagName("div"); // order: first, second, third 2 divs[0].parentNode.appendChild(divs[0]); // order: second, third, first 3 divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, third
appendChild() 方法:可向節點的子節點列表的末尾添加新的子節點。語法:appendChild(newchild)
insertBefore() 方法:可在已有的子節點前插入一個新的子節點。語法 :insertBefore(newchild,refchild)
相同之處:插入子節點
什麼是DOM,DOM使用了什麼數據結構?
HTML DOM 定義了訪問和操做獲取、修改、添加或刪除 HTML 元素的標準方法。DOM 將 HTML 文檔表達爲樹結構。
可經過 JavaScript (以及其餘編程語言)對 HTML DOM 進行訪問。
1 如何理解CSS中的盒子模型? Margin和Padding的區別是什麼?
邊框border 內邊距 外邊距。
Margin是外邊距,padding是內邊距。
http://www.w3school.com.cn/css/css_boxmodel.asp
2 如何驗證(validate)一個 HTML文件和CSS文件?
通常sublime這樣的編輯器,都會對html和css文件進行語法驗證。
http://jigsaw.w3.org/css-validator/
3 解釋在這個CSS 選擇器(selector)中發生了什麼:
[role=navigation] > ul a:not([href^=mailto]) {
}
定義了role
屬性,而且值爲navigation
的任何元素,其子元素列表下的除郵箱連接以外的全部連接元素。
在 CSS 中,選擇器是一種模式,用於選擇須要添加樣式的元素。上述css 選擇器主要使用了下面的三種模式:
[target=_blank] |
選擇 target="_blank" 的全部元素 |
div>p |
選擇父元素爲 <div> 元素的全部 <p> 元素。 |
:not(p) |
選擇非 <p> 元素的每一個元素。 |
什麼是LESS? <LESS>(選作)
Less 擴充了 CSS 語言,增長了諸如變量、混合(mixin)、運算、函數等。 Less 既能夠運行在服務器端(Node.js 和 Rhino 平臺)也能夠運行在客戶端(瀏覽器)。Sass、LESS和Stylus是CSS預處理器。他是CSS上的一種抽象層。他們是一種特殊的語法/語言編譯成CSS。
如何理解JS是單線程這一說法?爲何不會卡住?
Javascript除了一個主線程外,還配有一個代碼隊列,這個隊列用以存放定時器、HTTP請求、事件響應的回調。
什麼是瀏覽器事件模型?請描述js的事件冒泡和捕獲(event bubble and capturing), 如何中止冒泡(bubble)?
瀏覽器事件模型與js事件模型是同一個概念。
假設你在一個元素中又嵌套了另外一個元素
-----------------------------------
| element1 |
| ------------------------- |
| |element2 | |
| ------------------------- |
| |
-----------------------------------
:而且二者都有一個onClick事件處理函數(event handler)。若是用戶單擊元素2,則元素1和元素2的單擊事件都會被觸發。可是哪個事件先被觸發?哪個事件處理函數會被首先執行?換句話說,事件的發生順序到底如何?
兩種模型
不出所料,在那些「不堪回首」(瀏覽器大戰)的日子裏,Netscape和微軟有兩種大相徑庭的處理方法:
W3c明智的在這場爭鬥中選擇了一個擇中的方案。任何發生在w3c事件模型中的事件,首是進入捕獲階段,直到達到目標元素,再進入冒泡階段
| | / \
-----------------| |--| |-----------------
| element1 | | | | |
| -------------| |--| |----------- |
| |element2 \ / | | | |
| -------------------------------- |
| W3C event model |
------------------------------------------
爲一個web開發者,你能夠選擇是在捕獲階段仍是冒泡階段綁定事件處理函數,這是經過addEventListener()方法實現的,若是這個函數的最後一個參數是true,則在捕獲階段綁定函數,反之false,在冒泡階段綁定函數。
(如何選擇在哪一個階段綁定事件處理函數?)
如何取消冒泡?
在微軟的模型中,你必須設置事件的cancelBubble的屬性爲true:
1 window.event.cancelBubble = true
在w3c模型中你必須調用事件的stopPropagation()方法:
1 e.stopPropagation()
這會阻止全部冒泡向外傳播。
在js中咱們爲何須要event delegation?簡要描述一下事件委託?
現在的JavaScript技術界裏最火熱的一項技術應該是‘事件委託(event delegation)’了。使用事件委託技術能讓你避免對特定的每一個節點添加事件監聽器;相反,事件監聽器是被添加到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪一個子元素的事件。 也就是說把監聽子元素上的事件監聽函數放在它的父元素上來。
Ajax的全稱?原理?優勢?
全稱:Asynchronous js and xml
原理:Ajax的原理簡單來講經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。
把服務器端當作一個數據接口(只負責吐數據),它返回的是一個純文本流,固然,這個文本流能夠是XML格式,能夠是Html,能夠是Javascript代碼,也能夠只是一個字符串。這時候,XMLHttpRequest向服務器端請求這個頁面,服務器端將文本的結果寫入頁面,這和普通的web開發流程是同樣的,不一樣的是,客戶端在異步獲取這個結果後,不是直接顯示在頁面,而是先由javascript來處理,而後再顯示在頁面。
優勢: 局部刷新,避免從新刷新整個頁面。
什麼是XMLHTTPRequest對象?
XMLHttpRequest是ajax的核心機制,是JavaScript的一個內置對象。它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript能夠及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。
1 if (window.XMLHttpRequest)
2 {// code for all new browsers
3 xmlhttp=new XMLHttpRequest(); 4 }
多項選擇題:下列哪一項會返回‘true’?
AB.
A 擴展問題:null == undefined,若是是null === undefined,那是真是假? Null與undefined的區別是什麼?
undefined
表示一個變量聲明但未賦值:
1 var TestVar; 2 alert(TestVar); //shows undefined 3 alert(typeof TestVar); //shows undefined
undefined
is a type itself (undefined) while null
是一個對象。
總所周知:null == undefined
可是:null !== undefined
null這是一個對象,可是爲空。由於是對象,因此 typeof null 返回 'object' 。
一樣,當咱們定義一個變量但未賦予其初始值,例如:
var aValue;
這時,JavaScript在所謂的預編譯時會將其初始值設置爲對window.undefined屬性的引用,
Undefined Null 區別?
typeof 返回的是字符串,有六種可能:"number"、"string"、"boolean"、"object"、"function"、"undefined"
ECMAScript 有 5 種原始類型(primitive type),即 Number 、 String、Boolean、Undefined、Null。
Number 對象是原始數值的包裝對象。
1 var myNum=new Number(value);
2 var myNum=Number(value);
1 <script type=text/javascript>
2 var a = 123;
3 alert(typeof(a)); 4 </script>
typeof 一個函數的返回值是function,若是把這個function賦給一個var,則typeof的返回值是object。
==和===的區別是什麼?
javaScript has two sets of equality operators: ===
and !==
, and their evil twins ==
and !=
. The good ones work the way you would expect.
若是兩個操做數有相同的類型,並具備相同的值 then ===
produces true
and !==
produces false
.
The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable.
==和!=在兩個操做數類型相同的時候,會根據值是否相等來判斷。 若是類型不相同,那就邪惡了。。
C: 對於不等於1的整數,爲false;
DEF:A NaN按照定義永遠不等於它本身。. 在任何語言中都是這樣。. 在js中NaN是爲一個一個不等於它自身的東東。
之因此Nan不等於它自己,是爲了實現bool IsNaN(number)
函數:
1 function isNaN(x) 2 { 3 return x != x; 4 }
3 讀代碼,並寫出代碼的執行結果:
1 var t = true; 2 window.setTimeout(function (){ 3 t = false; 4 },1000); 5 while (t){} 6 alert('end');
Output: 沒有輸出,死循環。
分析:
確實是死循環致使setTimeout不執行,也致使alert不執行。
js是單線程是對的,因此會先執行while(t){}再alert,但這個循環體是死循環,因此永遠不會執行alert。
至於說爲何不執行setTimeout,是由於js的工做機制是:當線程中沒有執行任何同步代碼的前提下才會執行異步代碼,setTimeout是異步代碼,因此setTimeout只能等js空閒纔會執行,但死循環是永遠不會空閒的,因此setTimeout也永遠不會執行。
深刻理解js單線程:
JavaScript引擎是單線程運行的,瀏覽器不管在何時都只且只有一個線程在運行JavaScript程序。
1、瀏覽器的內核是多線程的,它們在內核制控下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:javascript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。
1. javascript引擎是基於事件驅動單線程執行的,JS引擎一直等待着任務隊列中任務的到來,而後加以處理,瀏覽器不管何時都只有一個JS線程在運行JS程序。
2. GUI渲染線程負責渲染瀏覽器界面,當界面須要重繪(Repaint)或因爲某種操做引起迴流(reflow)時,該線程就會執行。但須要注意 GUI渲染線程與JS引擎是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JS引擎空閒時當即被執行。
3. 事件觸發線程,當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeOut、也可來自瀏覽器內核的其餘線程如鼠標點擊、AJAX異步請求等,但因爲JS的單線程關係全部這些事件都得排隊等待JS引擎處理。(當線程中沒有執行任何同步代碼的前提下才會執行異步代碼)
什麼是遞歸? (遞歸是一個通用的概念。不只限於js)
什麼是閉包?
在js中,若是你在一個function中使用了另一個function關鍵字,你就建立了一個閉包。
1 function say667() {
2 // Local variable that ends up within closure
3 var num = 42; 4 var say = function() { console.log(num); } 5 num++; 6 return say; 7 } 8 var sayNumber = say667(); 9 sayNumber(); // logs 43
閉包(上述代碼中的匿名函數)中,保存的是outter函數的local變量的一個引用。
Output:43
分析: 閉包。1.函數嵌套函數2.函數內部能夠訪問到外部的變量或者對象3.避免了垃圾回收。
js在處理對象時,永遠使用引用reference。 好比說,你使用foo調用了一個對象,那麼返回的閉包將引用那個原始的對象。
1 function foo(x) {
2 var tmp = 3; 3 4 return function (y) { 5 console.log(x + y + tmp); 6 x.memb = x.memb ? x.memb + 1 : 1; 7 console.log(x.memb); 8 } 9 } 10 11 var age = new Number(2); 12 var bar = foo(age); // bar is now a closure referencing age. 13 bar(10);
As expected, each call to bar(10)
will increment x.memb
. What might not be expected, is that x
is simply referring to the same object as the age
variable! After a couple of calls to bar
, age.memb
will be 2! This referencing is the basis for memory leaks with HTML objects.
http://stackoverflow.com/questions/111102/how-do-javascript-closures-work
1 <script> 2 function sayAlice() { 3 var say = function() { alert(alice); } 4 var alice = 'Hello Alice'; 5 return say; 6 } 7 sayAlice()(); 8 </script>
Output:Hello Alice
分析:若是把sayAlice()();改成sayAlice()會怎麼樣?
1 <script> 2 function foo(x) { 3 var tmp = 3; 4 return function (y) { 5 alert(x + y + (++tmp)); 6 } 7 } 8 var bar = foo(2); 9 bar(10); 10 </script>
Output:16
分析:閉包。
1 <script> 2 var a = 10; 3 function test() { 4 alert(a); 5 alert(b); 6 } 7 var b = 6; 8 test(); 9 </script>
Output:10 6
分析:跟viriable hoisting 什麼區別?這也是一個閉包嗎?
When a JavaScript function is invoked, a new execution context is created. Together with the function arguments and the parent object, this execution context also receives all the variables declared outside of it (in the above example, both 'a' and 'b').
上述代碼,若是使用c語言實現,會輸出什麼結果??
上述代碼,若是使用Java實現,
1 <script> 2 function foo(x) { 3 var tmp = 3; 4 return function (y) { 5 alert(x + y + tmp); 6 x.memb = x.memb ? x.memb + 1 : 1; 7 alert(x.memb); 8 } 9 } 10 var age = new Number(2); 11 var bar = foo(age); // bar is now a closure referencing age. 12 bar(10); 13 </script>
Output: 15 1
1 <script> 2 var foo = {}; 3 foo.bar = 'hello'; 4 alert(foo.length); 5 </script>
Output:undefined
1 <script> 2 function hi(){ 3 var a; 4 alert(a); 5 } 6 hi(); 7 </script>
Output:undefined
問題: 與不使用hi 函數什麼區別? 也造成了閉包,可是a不是在Outter space定義的。
1 function addTen(num) { 2 num += 10; 3 return num; 4 } 5 6 var count = 20; 7 var result = addTen(count); 8 alert(count); 9 alert(result);
output : 20 30 考察js的參數傳遞
js與java相似,本質上都是值傳遞,可是引用是地址,值傳遞時拷貝了引用值的副本,但兩個引用指向的仍是同一個內存地址。
1 function setName(obj) { 2 obj.name = "Nicholas"; 3 obj = new Object(); 4 obj.name = "Greg"; 5 } 6 var person = new Object(); 7 setName(person); 8 alert(person.name)
output:Nicholas
分析: 主要考察引用傳遞。
JavaScript 是面向對象的語言,但 JavaScript 不使用類。
在 JavaScript 中,不會建立類,也不會經過類來建立對象(就像在其餘面向對象的語言中那樣)。
1 var city = "Rome"+function() { 2 console.log(city); 3 var city = "Paris"; 4 }();
output: undefined
分析:爲何?
(variable hoisting) 在Js中,變量被移動到腳本的頂部,而後執行。可是這種說法並不許確。在下面的代碼中:
1 console.log(a); 2 var a = 'Hello World!';
會輸出 undefined
, 並非 'Hello World'
, 因此上述代碼等效於下面的代碼:
1 var a; 2 console.log(a); 3 a = 'Hello World!';
而不是下面的代碼:
1 var a = 'Hello World!'; 2 console.log(a);
實際上,js並無移動任何代碼,你須要理解js的執行上下文(context): context分爲兩個階段:建立階段和執行階段。 在建立階段,爲這些變量和函數建立內存空間,人們每每把這個階段與variable hoisting混淆起來。 對於變量的賦值,是在執行上下文的執行階段進行的。當你對變量a賦值「Hello World」的時候,js引擎只有在執行階段才知道a的值,在建立階段,js只是把一個undefined的佔位符放在那裏,因此全部的變量都是被初始化爲undefined的。 因此建議永遠把變量聲明和函數放在你的代碼的頂部。
1 var name = "The Window"; 2 var object = { 3 name: "My Object", 4 getNameFunc: function () { 5 return function () { 6 return this.name; 7 }; 8 } 9 }; 10 alert(object.getNameFunc()());
output: The Window
分析: 閉包?
1 var name = "The Window"; 2 var object = { 3 name: "My Object", 4 getNameFunc: function () { 5 var that = this; 6 return function () { 7 return that.name; 8 }; 9 } 10 }; 11 alert(object.getNameFunc()());
output: My Object
分析:this指的是調用函數的那個對象
當點擊button#2的時候,console中會打印什麼?
1 var nodes = document.getElementsByTagName('button'); 2 // assume there is totally 5 nodes 3 for (var i = 0; i < nodes.length; i++) { 4 nodes[i].addEventListener('click', function() { 5 console.log('You clicked element #' + i); 6 }); 7 }
Output: you clicked element #5
分析: 閉包?
1 element.addEventListener('click', function() { /* do stuff here*/ }, false);
最後一個參數決定這個linstener如何響應bubbling事件。
<input id="File1" type="file" name="up1"/>
<input id="File2" type="file" name="up1" />
<input id="File3" type="file" name="up2" />
選作:
1 function Mammal(name) { 2 this.name = name; 3 this.offspring = []; 4 } 5 Mammal.prototype.haveABaby = function () { 6 var newBaby = new Mammal("Baby " + this.name); 7 this.offspring.push(newBaby); 8 return newBaby; 9 } 10 11 Mammal.prototype.toString = function () { 12 return '[Mammal "' + this.name + '"]'; 13 }; // 到目前爲止,這 是一個Mammal對象的實現。 14 15 16 17 // 將Employee的原型指向Person的一個實例 18 19 // 由於Person的實例能夠調用Person原型中的方法, 因此Employee的實例也能夠調用Person原型中的全部屬性。 20 Cat.prototype = new Mammal(); 21 22 //修正constructor 23 Cat.prototype.constructor = Cat; 24 function Cat(name) { 25 this.name = name; 26 } 27 28 Cat.prototype.toString = function () { 29 return '[Cat "' + this.name + '"]'; 30 } // 到目前爲止,這是Mammal的一個子類Cat。 31 32 33 var someAnimal = new Mammal('Mr. Biggles'); 34 var myPet = new Cat('Felix'); 35 alert(someAnimal); 36 alert(myPet); 37 38 myPet.haveABaby(); 39 alert(myPet.offspring.length); 40 alert(myPet.offspring[0]);
Output:
[Mammal 「Mr. Biggles」]
[Cat, 「Felix」]
1
[Mammal 「Baby Felix」]
進一步問題:什麼是prototype?什麼是原型鏈?
1 console.log("New york"); 2 setTimeout(function () { 3 console.log("Vienne"); 4 }, 1000); 5 setTimeout(function () { 6 console.log("London"); 7 }); 8 console.log("Ottawa");
Output: New York, Ottawa,Landon,Vienne。
分析:setTimeout異步函數。
1 嘗試實現下面的需求:
(1) 測試array numbers中是否是每個元素都比2大
E.G.
1 var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; 2 var everyResult = numbers.every(function (item, index, array) { 3 return (item > 2); 4 }); 5 alert(everyResult); //false
分析:對數組中的每一個元素都執行一次指定的函數(callback),直到此函數返回 false,若是發現這個元素,every 將返回 false,若是回調函數對每一個元素執行後都返回 true ,every 將返回 true。
(2) 獲得新的array,其中的元素是numbers中全部比2大的元素。
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
1 <script> 2 var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; 3 var numbersLargerThan2 = []; 4 for(i in numbers){ // i has some problems here. 5 if(numbers[i]>2) { 6 numbersLargerThan2.push(numbers[i]); 7 } 8 } 9 for(i in numbersLargerThan2) { 10 alert(numbersLargerThan2[i]); 11 } 12 // push pop 13 </script>
(3) 一個新的array,其中的每個元素都比numbers中的元素大1
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
1 //一個新的array,其中的每個元素都比numbers中的元素大1 2 <script> 3 var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]; 4 var numbersAfterAdd1 = []; 5 for(i in numbers) { 6 numbersAfterAdd1.push(numbers[i]+1); 7 } 8 9 for(i in numbersAfterAdd1) { 10 alert(numbersAfterAdd1[i]); 11 } 12 </script>
2列出js中建立對象的方法,並寫出一個js中的繼承關係的實現。
應該知道4種常見建立對象的方法:
1 用{} , 對象字面量。
先建立再添加:
1 //建立一個簡單對象字面量 2 var person = {}; 3 // 加入屬性和方法 4 person.name = 'ifcode'; 5 person.setName = function(theName) { 6 person.name = theName; 7 }
2 JS good parts中推薦這種寫法:
1 var person = { 2 name: 'ifcode', 3 setName: function(theName) { 4 this.name = theName; 5 } 6 }
1 var clock={ 2 hour:12, 3 minute:10, 4 second:10, 5 showTime:function(){ 6 alert(this.hour+":"+this.minute+":"+this.second); 7 } 8 } 9 clock.showTime();//調用 10 //var m = new myObj(); //不支持
上述兩種方式只存在於一個實例的對象,也就是單例模式。
下面是能夠建立多個實例的方式:
3 構造函數通常都符合factory pattern,根據默認的規則,構造函數應當首字母大寫:
1 Person = function(defaultName) { 2 this.name = defaultName; 3 this.setName = function(theName) { 4 this.name = theName; 5 } 6 } 7 person = new Person('ifcode'); // new是調用構造函數
利用構造函數就能夠方便地建立多個對象實例了。
4 利用 prototype的構造函數:
1 Person = function(defaultName) { 2 this.name = defaultName; 3 } 4 5 6 Person.prototype.setName = function(theName) { 7 this.name = theName; 8 }
全部建立在prototype上得屬性和方法,都將被全部對象實例分享。
通常在建立單例的時候,用2 ,在建立多個對象的時候,使用4.;
----------------------------------
2.建立Object實例
1 var clock = new Object(); 2 clock.hour=12; 3 clock.minute=10; 4 clock.showHour=function(){alert(clock.hour);}; 5 6 clock.showHour();//調用
因而可知 屬性是能夠動態添加,修改的
3用 function 關鍵字模擬 class
上述兩種。。。
http://www.cnblogs.com/lucas/archive/2009/03/17/1411656.html
http://www.jianshu.com/p/f9a1203e33d0
js中繼承關係的實現:
JavaScript中要實現繼承,其實就是實現三層含義:
一、子類的實例能夠共享父類的方法;
二、子類能夠覆蓋父類的方法或者擴展新的方法;
三、子類和父類都是子類實例的「類型」。
什麼是prototype? 原型
什麼是原型鏈?
JavaScript 是基於原型的語言。當咱們調用一個對象的屬性時,若是對象沒有該屬性,JavaScript 解釋器就會從對象的原型對象上去找該屬性,若是原型上也沒有該屬性,那就去找原型的原型。這種屬性查找的方式被稱爲原型鏈(prototype chain)。
ES6 並無改變 JavaScript 基於原型的本質,只是在此之上提供了一些語法糖。class
就是其中之一。其餘的還有 extends
,super
和 static
。它們大多數均可以轉換成等價的 ES5 語法。
javascript是面向對象的,怎麼體現javascript的繼承關係?使用prototype來實現。
ES6中啓用了class關鍵字,如何使用該關鍵字實現繼承關係?
1 // ES6 中啓用了關鍵字 class
2 class Person {
3 constructor(name, gender, age) { 4 this.name = name; 5 this.gender = gender; 6 this.age = age; 7 } 8 tellAge() { 9 console.log(this.age); 10 } 11 } 12 13 var puya = new Person('PuYart', 'male', '21'); 14 puya.tellAge();
CLASS繼承
1 /*
2 *class:ES6及ES6以上纔有該方法。
3 *class的出現將原型繼承簡化了不少,class的目的就是讓定義類更簡單。
4 *extends來繼承對象,中間的原型之類的就能夠免去,就能夠繼承擴展class
5 */
6 //用class建立對象
7 class Leader{
8 constructor(name){//constructor構造函數
9 this.name=name; 10 } 11 hello(){//定義在原型上的函數 12 alert('Hello, '+this.name+'!'); 13 } 14 } 15 var liyi= new Leader('liyi'); 16 liyi.name;//輸出'liyi' 17 liyi.hello();//輸出'Hello, liyi!' 18 //用extends繼承擴展 19 class extendLeader extends Leader{ 20 constructor(name,grade,skill){//如果不擴展Leader的構造函數,就能夠將constructor這一步省去 21 super(name); 22 this.grade=grade; 23 this.skill=skill; 24 } 25 run(){ 26 console.log(this.name+'職位:'+this.grade+' 技能:'+this.skill); 27 } 28 } 29 var liyi=new extendLeader('liyi','研發經理','精通各類技術'); 30 liyi.name;//'liyi' 31 liyi.grade;//'研發經理' 32 liyi.skill;//'精通各類技術' 33 liyi.hello;//'Hello, liyi!' 34 liyi.run();//'liyi職位:研發經理 技能:精通各類技術'
Two awesome javascript inheritance libraries that come to mind are klass and selfish.js (I've used both, they're amazing.)
http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html
知不知道ES6 中的class和extends關鍵字,如何使用上述關鍵字實現一個繼承關係。
1 function Person(name) { 2 this.name = name; 3 } 4 5 Person.prototype = { 6 getName: function() { 7 return this.name; 8 } 9 } 10 11 function Employee(name, employeeID) { 12 this.name = name; 13 this.employeeID = employeeID; 14 } 15 16 // 這是很差的。 17 Employee.prototype = new Person(); 18 Employee.prototype.getEmployeeID = function() { 19 return this.employeeID; 20 }; 21 22 var zhang = new Employee("ZhangSan", "1234"); 23 console.log(zhang.getName()); // "ZhangSan"
1 function Employee(name, employeeID) { 2 this.name = name; 3 this.employeeID = employeeID; 4 } 5 // 建立Employee時實例化Person是不合適的 6 Employee.prototype = new Person(); 7 Employee.prototype.constructor = Employee; 8 Employee.prototype.getEmployeeID = function() {\ 9 return this.employeeID; 10 }; 11 12 var zhang = new Employee("ZhangSan", "1234"); 13 console.log(zhang.constructor === Employee); // true 14 console.log(zhang.constructor === Object); // false
提供一個原型方法(好比init)來初始化數據。
1 // 空的構造函數 2 function Person() { 3 } 4 5 Person.prototype = { 6 init: function(name) { 7 this.name = name; 8 }, 9 10 getName: function() { 11 return this.name; 12 } 13 } 14 15 // 空的構造函數 16 function Employee() { 17 } 18 19 // 建立類的階段不會初始化父類的數據,由於Person是一個空的構造函數 20 Employee.prototype = new Person(); 21 Employee.prototype.constructor = Employee; 22 Employee.prototype.init = function(name, employeeID) { 23 this.name = name; 24 this.employeeID = employeeID; 25 }; 26 27 Employee.prototype.getEmployeeID = function() { 28 return this.employeeID; 29 };
這種方式下,必須在實例化一個對象後手工調用init函數,以下:
1 var zhang = new Employee(); 2 zhang.init("ZhangSan", "1234"); 3 console.log(zhang.getName()); // "ZhangSan"
必須達到兩個效果,構造類時不要調用init函數和實例化對象時自動調用init函數。看來咱們須要在調用空的構造函數時有一個狀態標示。
能夠用 call 來實現繼承:
1 function Class1() { 2 this.showTxt = function(txt) { 3 alert(txt); 4 } 5 } 6 function Class2() { 7 Class1.call(this); 8 } 9 var c2 = new Class2(); 10 c2.showTxt("cc");
這樣 Class2 就繼承Class1了,Class1.call(this) 的 意思就是使用 Class1 對象代替this對象,那麼 Class2 中不就有Class1 的全部屬性和方法了嗎,c2 對象就可以直接調用Class1 的方法以及屬性了,執行結果就是:alert(「cc」);
變化太快。
JQuery做爲基礎。
1 如何使用JQuery選取一個ID爲myDivId的元素?如何選取一組class爲myCssClass的元素?寫出代碼。
1 $( "#myDivId" ); 2 $( ".myDivId" );
3 簡述你使用過的前端框架,並介紹其優缺點?
JQuery/Query Mobile
Dojo/Dojo Mobile
zepto.js是一個專爲mobile WebKit瀏覽器(如:Safari和Chrome), 語法借鑑併兼容JQuery。
Node.js
angularJS
bootstrap 是一套html css和js的框架。
React.js(React)是 Facebook 推出的一個用來構建用戶界面的 JavaScript 庫.
Slider 滑動條控件。(不算一個框架)
(選作)若是熟悉angularJS, 請選擇(1), 若是熟悉React, 請選擇(2):
(1) 描述angular中的數據綁定(data-binding),描述angular依賴注入(dependency injection)
在angular中,model和view組件之間的Data Binding是能夠自動同步數據的。angular實現Data Binding的方法可讓你確信在你的應用中model是single-source-of-truth,view僅僅是model的投影。當model改變時,view跟着改變,反之亦然。
angular的模板系統則不一樣,template是被瀏覽器去編譯的,編譯這步會產生一個live的view。對view進行的任何更改會當即反映到model中,對model進行的更改也會當即反映到view中。model是應用程序的single-source-of-truth,極大地簡化了開發人員的編程模型,你僅僅把view當成model的瞬間投影便可。
Angular JS框架與Spring相似,都實現了DI。
(2) virtual DOM的優點是什麼?解釋FLUX中的數據流
來人們使用了 MVC、MVP 的架構模式,但願能從代碼組織方式來下降維護這種複雜應用程序的難度。可是 MVC 架構沒辦法減小你所維護的狀態,也沒有下降狀態更新你須要對頁面的更新操做(前端來講就是DOM操做),你須要操做的DOM仍是須要操做,只是換了個地方。
相對於 DOM 對象,原生的 JavaScript 對象處理起來更快,並且更簡單。DOM 樹上的結構、屬性信息咱們均可以很容易地用 JavaScript 對象表示出來。
既然狀態改變了要操做相應的DOM元素,爲何不作一個東西可讓視圖和狀態進行綁定,狀態變動了視圖自動變動,就不用手動更新頁面了。這就是後來人們想出了 MVVM 模式。
React 標榜本身是 MVC 裏面 V 的部分,那麼 Flux 就至關於添加 M 和 C 的部分。
Flux 是 Facebook 使用的一套前端應用的架構模式。
一個 Flux 應用主要包含四個部分:
the dispatcher
處理動做分發,維護 Store 之間的依賴關係
the stores
數據和邏輯部分
the views
React 組件,這一層能夠看做 controller-views,做爲視圖同時響應用戶交互
the actions
提供給 dispatcher 傳遞數據給 store
Flux 的核心「單向數據流「怎麼運做的:
Action -> Dispatcher -> Store -> View
更多時候 View 會經過用戶交互觸發 Action,因此一個簡單完整的數據流相似這樣:
(選作)什麼是npm, 你能夠如何使用它?
npm是Node.js 的包管理工具,用來安裝各類 Node.js 的擴展。
請描述Git中merge和rebase的區別(選作)
git merge和git rebase從最終效果來看沒有任何區別,都是將不一樣分支的代碼融合在一塊兒,可是生成的代碼樹就稍微有些不一樣。rebase操做不會生成新的節點,是將兩個分支融合成一個線性的提交。而merge操做生成的代碼樹會顯得比較亂。
什麼是mock? (選作)
mock測試就是在測試過程當中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬的對象來建立以便測試的測試方法。
延伸問題:什麼是冒煙測試(smoke test)?
冒煙測試源自硬件行業,對一個硬件或者硬件組件改動後,直接給設備加電,看看設備會不會冒煙,沒冒煙,就表示待測組件是經過了測試。 在軟件開發過程當中,一直有高內聚,低耦合這樣的說法,各個功能模塊之間的耦合仍是存在的,所以一個功能的改動,仍是會影響到其餘功能模塊。 所以在開發人員修復了先前測試中發現的bug後,想知道這個bug的修復是否會影響到其餘功能模塊,須要作的就是冒煙測試。
列出你知道的前端的build/test automation/unit test/的工具/框架,以及你知道的其餘工具,並給出簡要描述。(選作)
靜態代碼檢查工具JSLint。 JSHint跟JSLint很是像,都是Javascript代碼驗證工具
前端的測試框架不少,像QUnit、jasmine、mocha、jest、intern等
QUnit誕生之初是爲了jquery的單元測試
Bower 包管理 包依賴
Yeoman 快速構建
Build工具:
Grunt能作什麼:
一、合併,壓縮JS,CSS。
二、單元測試(Qunit)。
三、驗證(JSHint)。
四、初始化一個Project。
Build工具:
Gulp + Webpack
這一部分主要考察對網絡協議,主要是HTTP協議的理解。
HTTP請求共有幾種類型?給出你經常使用的類型,並結合你給出的類型描述HTTP請求的冪等性。
8 種類型: GET POST PUT DELETE OPTION HEAD等等。
列出常見的HTTP請求的返回狀態(Status Code),並簡述其含義?
如何解決HTTP的無狀態性所帶來的問題?(選作)
如何理解HTTP是無鏈接的? (選作)
TCP是有鏈接的,而HTTP是無鏈接的。無鏈接:服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。
什麼是長鏈接?
HTTP響應碼 1 2 3 4 5 的各類含義
什麼是RESTful風格?
常見HTTP報頭的含義:
Via
Keep-alive
是否熟悉抓包工具,平時都使用什麼抓包工具? 好比Fiddler?
什麼是Proxy? 什麼是反向代理?
簡述什麼是MVC ?(選作)
什麼是websocket?什麼是REST?什麼樣的需求(使用場景)會須要websocket和REST?(選作)
其餘問題:
指望薪資;
如何看待加班,婚育狀況,住址,什麼時候到崗;
是否有問題須要提問?
快排的主要思想?時間複雜度? 如何避免最差的時間複雜度?(選作)
6二叉樹有哪些遍歷算法? 如何從遞歸算法構造非遞歸算法?使用什麼輔助數據結構?(選作)
4 什麼是平衡二叉樹?常見的平衡二叉樹有哪些?(選作)
如何選取特定的HTML元素?
Js
5 javascript的方法能夠分爲哪幾類?
類方法(靜態方法),對象方法(實例方法),原型方法。
javascript的方法能夠分爲三類:
a 類方法
b 對象方法
c 原型方法
例子:
1 function People(name)
2 { 3 this.name=name; 4 //對象方法 5 this.Introduce=function(){ 6 alert("My name is "+this.name); 7 } 8 } 9 //類方法 10 People.Run=function(){ 11 alert("I can run"); 12 } 13 //原型方法 14 People.prototype.IntroduceChinese=function(){ 15 alert("個人名字是"+this.name); 16 } 17 18 19 20 //測試 21 22 var p1=new People("Windking"); 23 24 p1.Introduce(); 25 26 People.Run(); 27 28 p1.IntroduceChinese();
1 什麼是document對象?如何經過Window對象訪問document對象?
9 是否熟悉抓包工具,平時都使用什麼抓包工具?
8 列出常見的HTTP報頭的字段,並簡述其含義?
Keep-alive什麼是長鏈接?
10 什麼是Proxy? 什麼是反向代理?
1 <script> 2 var foo = []; 3 foo.push(1); 4 foo.push(2); 5 alert(foo.length); 6 </script>
Output:2
什麼是平衡二叉樹?常見的平衡二叉樹有哪些?()AVL 紅黑。
算法:
快排的思想,時間複雜度? 如何避免最差的時間複雜度?
二叉樹的遍歷算法? 如何從遞歸算法構造非遞歸算法,使用什麼輔助數據結構?
5. js中的3種彈出式消息提醒(警告窗口,確認窗口,信息輸入窗口)的命令是什麼?alertconfirmprompt