1. 程式人生 > >前端開發人員問題四

前端開發人員問題四

detach undefined 速度 操作符 yun false outline 區分 isa

問題來源:http://markyun.github.io/2015/Front-end-Developer-Questions/

三、javascript
1、介紹JavaScript的基本數據類型。
答;1. Number 數字類型
2. String 字符串類型
3. Boolean 布爾類型
4. Function 函數
5. Object 對象
6. Null
7. Undefined 沒有定義類型

2、說說寫JavaScript的基本規範?
答:1、命名規範
1-1,javascript文件:js後綴為.js中,盡量減少html中的js代碼。因為存在js代碼會明顯增加文件大
小,且不能對其進行緩存和壓縮。
1-2,縮進單位是4個空格。避免使用tab鍵來縮進。因為tab始終沒有統一tab長短標準,空格會增加文
件的大小,但是可以忽略。
1-3,每行長度不超過80個字符。
1-4。註釋,讓註釋有意義
1-5,變量聲明。所有變量必須在使用前通過var進行申明。
1-6,函數聲明。所有函數在使用前進行聲明。
1-7,命名。大小寫字母,10個數字和下劃線組成。

2、封裝技巧
js是腳本語言。基於ECMA腳本設計的語言,還能巧妙的設計實現一些面向對象語言的基本特性。例如:
類,多態,繼承。。。。

2.1類:靜態類和普通類
2.1.1靜態類
通過一個簡單的object對象來模擬一個靜態類。
//定義靜態類
var
2.1.2普通類
普通類通過function來模擬的,我們通過new關鍵字來實現當前類的一個實例。

區別:靜態類和普通類差別除了聲明上和訪問上不同外,普通類還有一個特點就是我們可以定義訪問類
中的成員的訪問級別。而靜態類中所有的成員都是public。

2.2繼承
js中繼承是通過他本身的原型機制實現的,js下的繼承分為:原型繼承和原型子類繼承。
2.2.1原型繼承

2.2.2原型子類繼承


2.3重載
由於js的方法名如果相同,方法被覆蓋,所以我們只能變相實現重載。

3、jquery使用建議
3.1盡量減少jquery提供的對dom元素的訪問和操作方法
3.2優先采用jquery擴展函數,並且使用jq連寫和選擇表達式來減少代碼行數。
3.3盡量避免給dom元素綁定多個相同類型的事件處理函數,可以將多個相同類型時間處理函數合並到一
個處理函數,通過數據狀態來處理分支。
3.4盡量避免使用toggle時間。

4、ajax使用
4.1頁面初次加載時,盡量在web服務器一次性輸出所有相關的數據,只在頁面加載完成之後,用戶進行
操作時采用采用ajax進行交互。
4.2同步ajax在iE上會產生頁面假死的問題。所以建議采用異步ajax。
4.3盡量減少ajax請求次數
4.4ajax安全問題,對於敏感數據在服務器端處理,避免在客戶端處理過濾,比如compass list數據。
對於關鍵的業務邏輯代碼也必須放在服務器端處理。

5、JavaScript有幾種類型的值?(堆:原始數據類型和 棧:引用數據類型),你能畫一下他們的內存
圖嗎?
答:基本數據類型存儲在棧中,引用數據類型(對象)存儲在堆中,指針放在棧中。兩種類型的區別是
:存儲位置不同;原始數據類型直接存儲在棧(stack)中的簡單數據段,占據空間小、大小固定,屬於
被頻繁使用數據,所以放入棧中存儲;引用數據類型存儲在堆(heap)中的對象,占據空間大、大小不固
定,如果存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該
實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址後從堆中獲得實體。

6、Javascript如何實現繼承?
答:構造繼承,原型繼承,(實例繼承,拷貝繼承)。構造函數繼承可以將構造函數的屬性拷貝給實例
(*.call(this,[]))。但是缺點是無法實現函數復用。原型繼承可以實現函數復用,但是所有實例共
享一個屬性,任意一個實例改變原型屬性都會改變其它實例的屬性值。推薦采用構造函數繼承傳遞屬性
(拷貝),原型繼承傳遞方法。

7、Javascript創建對象的幾種方式?
答:1.對象字面量的方式,var obj={};{}是字面量,可以立即求值;2.用function來模擬無參的構造
函數,再定義屬性;3.用function模擬構造函數,利用this;function Rectangle(w,h)
{this.width=w;this.height=h;} var rect=new Rectangle(4,8); 4.利用工廠方式(內置對象
Object,本質是方法),var obj=new Object();;5.利用原型方式來創建;6.混合方式來創建。

8、Javascript作用鏈域?
答;當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈。如果是個函數,則將其活動對象作
為變量對象。活動對象在最開始只包含一個arguments對象。而下一個變量對象則來自下一個包含環境
。如此一直延續到全局執行環境,這種組織形式即為作用域鏈。內部函數可訪問外部變量,外部變量無
法訪問內部函數。註意:js沒有塊級作用域,若要形成塊級作用域,可通過(function(){})()
;立即執行的形式實現。

9、談談This對象的理解。
答:(1)this總是指向函數的直接調用者(而非間接調用者)
(2)如果有new關鍵字,this指向new出來的那個對象
(3)在事件中,this指向觸發這個事件的對象,特殊的是IE的attachEvent中的this總是指向全局對象
window。

10、eval是做什麽的?
答:計算某個字符串,並執行其中的js代碼。eval(string),這樣避免使用eval,不安全,耗性能。
由json字符串轉換成json對象可以使用eval,var obj=eval(‘(‘+ str +‘)‘)

11、什麽是window對象? 什麽是document對象?
答:window對象代表瀏覽器中打開的一個窗口。document對象代表整個html文檔。實際上,document對
象是window對象的對象屬性。

12、null,undefined的區別?
答:null表示一個對象被定義了,但存放了空指針。undefined表示這個值不存在。typeof(null)--
object;typeof(undefined)--undefined

13、寫一個通用的事件偵聽器函數(機試題)。
答:// 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.datachEvent) {
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;
}
};

14、["1", "2", "3"].map(parseInt) 答案是多少?
答;為何返回不是 [1,2,3] 卻是 [1,NaN,NaN]?原因:parseInt接收的是兩個參數,map傳遞的是3個參
數。
(1)parseInt函數:parseInt(string, radix);string: 需要轉化的字符,如果不是字符串會被轉換,
忽視空格符。radix:數字2-36之前的整型。默認使用10,表示十進制。需要註意的是,如果radix在2
-36之外會返回NaN。
(2)map函數:arr.map(callback[,thisArg]);

15、關於事件,IE與火狐的事件機制有什麽區別? 如何阻止冒泡?
答:IE為事件冒泡,Firefox同時支持事件捕獲和冒泡事件。但並非所有瀏覽器都支持事件捕獲。
jQuery中使用event.stopPropagation()方法可阻止冒泡;(舊ie的方法 ev.cancelBubble = true;)

16、什麽是閉包(closure),為什麽要用它?
答:閉包指的是一個函數可以訪問另一個函數作用域中變量的函數。常見的構造方法,是在一個函數內
部定義另外一個函數。內部函數可以引用外層的參數和變量;參數和變量不會被垃圾回收機制回收。註
意,閉包的原理是作用域鏈,所以閉包訪問的上級作用域中的變量是個對象,其值為其運算結束後的最
後一個值。除非用立即執行函數來解決。

17、javascript 代碼中的"use strict";是什麽意思 ? 使用它區別是什麽?
答:除了正常模式運行外,ECMAscript添加了第二種運行模式:“嚴格模式”。
區別:(1)消除js不合理,不嚴謹地方,減少怪異行為
(2)消除代碼運行的不安全之處,
(3)提高編譯器的效率,增加運行速度
(4)為未來的js新版本做鋪墊。

18、如何判斷一個對象是否屬於某個類?
答:使用instanceof 即if(a instanceof Person){alert(‘yes‘);}

19、new操作符具體幹了什麽呢?
答:1、創建一個空對象,並且 this 變量引用該對象,同時還繼承了該函數的原型。p._proto_ =
Base.prototype;
2、屬性和方法被加入到 this 引用的對象中。Base.call(p/this)
3、新創建的對象由 this 所引用,並且最後隱式的返回 this 。

20、用原生JavaScript的實現過什麽功能嗎?
答:(1)顯示和隱藏
jq:
$(el).show();
$(el).hide();

js:
el.style.display = ‘‘;
el.style.display = ‘none‘;

(2)淡入淡出
jq:$(el).fadeIn();  
js:function fadeIn(el) {
var opacity = 0;

el.style.opacity = 0;
el.style.filter = ‘‘;

var last = +new Date();
var tick = function() {
opacity += (new Date() - last) / 400;
el.style.opacity = opacity;
el.style.filter = ‘alpha(opacity=‘ + (100 * opacity)|0 + ‘)‘;

last = +new Date();

if (opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick,
16);
}
};

tick();
}

fadeIn(el);

21、Javascript中,有一個函數,執行時對象查找時,永遠不會去查找原型,這個函數是?
答:Object.hasOwnProperty(proName):是用來判斷一個對象是否有你給出名稱的屬性或對象。不過需
要註意的是,此方法無法檢查該對象的原型鏈中是否具有該屬性,該屬性必須是對象本身的一個成員。
判斷對象是否有某個特定的屬性。必須用字符串指定該屬性。(例如,o.hasOwnProperty("name"))。

22、對JSON的了解?
答:JSON中對象通過“{}”來標識,一個“{}”代表一個對象,如{“AreaId”:”123”},對象的值是
鍵值對的形式(key:value)。
是js的一個嚴格的子集,一種輕量級的數據交換格式,類似於xml。數據格式簡單,易於讀寫,占用帶
寬小。兩個函數:JSON.parse(str)<檢查代碼 str--js對象>;JSON.stringify(obj);eval(‘(‘+json
+‘)‘)<不會檢查代碼,會直接執行>

23、[].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.random()*
(1<<24))).toString(16) }) 能解釋一下這段代碼的意思嗎?
答;獲取頁面中所有的元素,然後遍歷每個元素,為元素的style屬性增加一個顏色邊框。\

24、js延遲加載的方式有哪些?
答:js的延遲加載有助與提高頁面的加載速度。
(1)使用setTimeout延遲方法的加載時間 $(function (){
setTimeout(‘A()‘, 1000); //延遲1秒
})
(2)讓js最後加載
引入外部js腳本文件時,如果放入html的head中,則頁面加載前該js腳本就會被加載入頁面,而放入
body中,則會按照頁面從上倒下的加載順序來運行javascript的代碼~~~ 所以我們可以把js外部引入的
文件放到頁面底部,來讓js最後引入,從而加快頁面加載速度。
(3)上述方法2也會偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這裏
的解決方案將是來自Google幫助頁面的推薦方案。
//這些代碼應被放置在</body>標簽前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
使用此段代碼的步驟:
1).復制上面代碼
2).粘貼代碼到HTML的標簽前 (靠近HTML文件底部)
3).修改“defer.js”為你的外部JS文件名
4).確保你文件路徑是正確的。例如:如果你僅輸入“defer.js”,那麽“defer.js”文件一定與HTML
文件在同一文件夾下。

25、Ajax 是什麽? 如何創建一個Ajax?
答:(1)ajax的全稱:Asynchronous Javascript And XML。所謂異步,在這裏簡單地解釋就是:向服
務器發送請求的時候,我們不必等待結果,而是可以同時做其他的事情,等到有了結果它自己會根據設
定進行後續操作,與此同時,頁面是不會發生整頁刷新的,提高了用戶體驗。
(2)(1)創建XMLHttpRequest對象,也就是創建一個異步調用對象 (考慮IE6的兼容性,new
XMLHttpRequest());
(2)創建一個新的HTTP請求,並指定該HTTP請求的方法、URL及驗證信息 (xhr.open
("get"),"example.php",true);
(3)設置響應HTTP請求狀態變化的函數
(4)發送HTTP請求
(5)獲取異步調用返回的數據
(6)使用JavaScript和DOM實現局部刷新
註:http請求過程:1、建立tcp連接。2、web瀏覽器向web服務器發送請求指令。3、web瀏覽器發送請
求頭信息。4、web服務器應答。5、web服務器發送應答頭信息。6、web服務器向瀏覽器發送數據。7、
web服務器關閉tcp連接。

26、同步和異步的區別?
答:同步的概念是os中:不同進程協同完成某項工作而先後次序調整(通過阻塞、喚醒等方式),同步
強調的是順序性,誰先誰後。。異步不存在順序性。同步:瀏覽器訪問服務器,用戶看到頁面刷新,重
新發請求,等請求完,頁面刷新,新內容出現,用戶看到新內容之後進行下一步操作。異步:瀏覽器訪
問服務器請求,用戶正常操作,瀏覽器在後端進行請求。等請求完,也買你不刷新,新內容也會出現,
永輝看到新內容。

27、如何解決跨域問題?
答:(1)同源策略:在同一個域名下或者同一域名不同文件夾,只有這兩個是允許通信的。
特別註意兩點:
第一,如果是協議和端口造成的跨域問題“前臺”是無能為力的,
第二:在跨域問題上,域僅僅是通過“URL的首部”來識別而不會去嘗試判斷相同的ip地址對應著兩個
域或兩個域是否在同一個ip上。
(2)參考,寫的很不錯:http://www.cnblogs.com/JChen666/p/3399951.html

28、頁面編碼和被請求的資源編碼如果不一致如何處理?
答:若請求的資源編碼,如外引js文件編碼與頁面編碼不同。可根據外引資源編碼方式定義為
charset="utf-8"或"gbk"。

29、模塊化開發怎麽做?
答:模塊化開發指的是在解決某一個復雜問題或者一系列問題時,依照一種分類的思維吧問題進行系統
性的分解以之解決。模塊化是一種處理復雜系統分解為代碼結構更合理,可維護性更高的可管理的模塊
方式。對於軟件行業:系統被分解為一組高內聚,低耦合的模塊。
(1)定義封裝的模塊
(2)定義新模塊對其他模塊的依賴
(3)可對其他模塊的引入支持
在JavaScript中出現了一些非傳統模塊開發方式的規範 CommonJS的模塊規範,AMD(Asynchronous
Module Definition),CMD(Common Module Definition)等

AMD是異步模塊定義,所有的模塊將被異步加載,模塊加載不影響後邊語句運行。

30、AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)規範區別?
答 :參考這個http://blog.chinaunix.net/uid-26672038-id-4112229.html
解釋:AMD 是 RequireJS 在推廣過程中對模塊定義的規範化產出。
CMD 是 SeaJS 在推廣過程中對模塊定義的規範化產出。
區別:
1. 對於依賴的模塊,AMD 是提前執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改成
可以延遲執行(根據寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
2. CMD 推崇依賴就近,AMD 推崇依賴前置。
3. AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。

未完待續

前端開發人員問題四