說說最近最流行的一些東西吧?常去哪些網(wǎng)站?
成組腳本:由于每個(gè)標(biāo)簽下載時(shí)阻塞頁面解析過程,所以限制頁面的總數(shù)也可以改善性能。適用于內(nèi)聯(lián)腳本和外部腳本。
非阻塞腳本:等頁面完成加載后,再加載js代碼。也就是,在window.onload事件發(fā)出后開始下載代碼。 (1)defer屬性:支持IE4和fierfox3.5更高版本瀏覽器 (2)動(dòng)態(tài)腳本元素:文檔對(duì)象模型(DOM)允許你使用js動(dòng)態(tài)創(chuàng)建HTML的幾乎全部文檔內(nèi)容。代碼如下:
var script=document.createElement("script");
script.type="text/javascript";
script.src="file.js";
document.getElementsByTagName("head")[0].appendChild(script);
此技術(shù)的重點(diǎn)在于:無論在何處啟動(dòng)下載,文件額下載和運(yùn)行都不會(huì)阻塞其他頁面處理過程。即使在head里(除了用于下載文件的http鏈接)。
閉包相關(guān)問題?
詳情請(qǐng)見:詳解js閉包
js事件處理程序問題?
詳情請(qǐng)見:JavaScript學(xué)習(xí)總結(jié)(九)事件詳解
eval是做什么的?
它的功能是把對(duì)應(yīng)的字符串解析成JS代碼并運(yùn)行;
應(yīng)該避免使用eval,不安全,非常耗性能(2次,一次解析成js語句,一次執(zhí)行)。
JavaScript原型,原型鏈?有什么特點(diǎn)?
*原型對(duì)象也是普通的對(duì)象,是對(duì)象一個(gè)自帶隱式的__proto__屬性,原型也有可能有自己的原型,如果一個(gè)原型對(duì)象的原型不為null的話,我們就稱之為原型鏈。
*原型鏈?zhǔn)怯梢恍┯脕砝^承和共享屬性的對(duì)象組成的(有限的)對(duì)象鏈。
事件、IE與火狐的事件機(jī)制有什么區(qū)別? 如何阻止冒泡?
1.我們?cè)诰W(wǎng)頁中的某個(gè)操作(有的操作對(duì)應(yīng)多個(gè)事件)。例如:當(dāng)我們點(diǎn)擊一個(gè)按鈕就會(huì)產(chǎn)生一個(gè)事件。是可以被JavaScript偵測(cè)到的行為。
2.事件處理機(jī)制:IE是事件冒泡、firefox同時(shí)支持兩種事件模型,也就是:捕獲型事件和冒泡型事件。;
3. ?ev.stopPropagation();注意舊ie的方法ev.cancelBubble = true;
ajax是什么?ajax的交互模型?同步和異步的區(qū)別?如何解決跨域問題?
詳情請(qǐng)見:JavaScript學(xué)習(xí)總結(jié)(七)Ajax和Http狀態(tài)字
1.通過異步模式,提升了用戶體驗(yàn)
2.優(yōu)化了瀏覽器和服務(wù)器之間的傳輸,減少不必要的數(shù)據(jù)往返,減少了帶寬占用
3. Ajax在客戶端運(yùn)行,承擔(dān)了一部分本來由服務(wù)器承擔(dān)的工作,減少了大用戶量下的服務(wù)器負(fù)載。
2. Ajax的最大的特點(diǎn)是什么。
Ajax可以實(shí)現(xiàn)動(dòng)態(tài)不刷新(局部刷新)
readyState屬性 狀態(tài) 有5個(gè)可取值:0=未初始化 ,1=啟動(dòng)2=發(fā)送,3=接收,4=完成
ajax的缺點(diǎn)
1、ajax不支持瀏覽器back按鈕。
2、安全問題AJAX暴露了與服務(wù)器交互的細(xì)節(jié)。
3、對(duì)搜索引擎的支持比較弱。
4、破壞了程序的異常機(jī)制。
5、不容易調(diào)試。
跨域:jsonp、iframe、window.name、window.postMessage、服務(wù)器上設(shè)置代理頁面
js對(duì)象的深度克隆
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = []; ?//創(chuàng)建一個(gè)空的數(shù)組
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
}else if (Obj instanceof Object){
buf = {}; ?//創(chuàng)建一個(gè)空對(duì)象
for (var k in Obj) { ?//為這個(gè)對(duì)象添加新的屬性
buf[k] = clone(Obj[k]);
}
return buf;
}else{
return Obj;
}
}
AMD和CMD規(guī)范的區(qū)別?
詳情請(qǐng)見:詳解JavaScript模塊化開發(fā)
網(wǎng)站重構(gòu)的理解?
網(wǎng)站重構(gòu):在不改變外部行為的前提下,簡(jiǎn)化結(jié)構(gòu)、添加可讀性,而在網(wǎng)站前端保持一致的行為。也就是說是在不改變UI的情況下,對(duì)網(wǎng)站進(jìn)行優(yōu)化,在擴(kuò)展的同時(shí)保持一致的UI。
對(duì)于傳統(tǒng)的網(wǎng)站來說重構(gòu)通常是:
表格(table)布局改為DIV+CSS
使網(wǎng)站前端兼容于現(xiàn)代瀏覽器(針對(duì)于不合規(guī)范的CSS、如對(duì)IE6有效的)
對(duì)于移動(dòng)平臺(tái)的優(yōu)化
針對(duì)于SEO進(jìn)行優(yōu)化
深層次的網(wǎng)站重構(gòu)應(yīng)該考慮的方面
減少代碼間的耦合
讓代碼保持彈性
嚴(yán)格按規(guī)范編寫代碼
設(shè)計(jì)可擴(kuò)展的API
代替舊有的框架、語言(如VB)
增強(qiáng)用戶體驗(yàn)
通常來說對(duì)于速度的優(yōu)化也包含在重構(gòu)中
壓縮JS、CSS、image等前端資源(通常是由服務(wù)器來解決)
程序的性能優(yōu)化(如數(shù)據(jù)讀寫)
采用CDN來加速資源加載
對(duì)于JS DOM的優(yōu)化
HTTP服務(wù)器的文件緩存
如何獲取UA?
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;
}
js數(shù)組去重
以下是數(shù)組去重的三種方法:
Array.prototype.unique1 = function () {
var n = []; //一個(gè)新的臨時(shí)數(shù)組
for (var i = 0; i < this.length; i++) //遍歷當(dāng)前數(shù)組
{
//如果當(dāng)前數(shù)組的第i已經(jīng)保存進(jìn)了臨時(shí)數(shù)組,那么跳過,
//否則把當(dāng)前項(xiàng)push到臨時(shí)數(shù)組里面
if (n.indexOf(this[i]) == -1) n.push(this[i]);
}
return n;
}
Array.prototype.unique2 = function()
{
var n = {},r=[]; //n為hash表,r為臨時(shí)數(shù)組
for(var i = 0; i < this.length; i++) //遍歷當(dāng)前數(shù)組
{
if (!n[this[i]]) //如果hash表中沒有當(dāng)前項(xiàng)
{
n[this[i]] = true; //存入hash表
r.push(this[i]); //把當(dāng)前數(shù)組的當(dāng)前項(xiàng)push到臨時(shí)數(shù)組里面
}
}
return r;
}
Array.prototype.unique3 = function()
{
var n = [this[0]]; //結(jié)果數(shù)組
for(var i = 1; i < this.length; i++) //從第二項(xiàng)開始遍歷
{
//如果當(dāng)前數(shù)組的第i項(xiàng)在當(dāng)前數(shù)組中第一次出現(xiàn)的位置不是i,
//那么表示第i項(xiàng)是重復(fù)的,忽略掉。否則存入結(jié)果數(shù)組
if (this.indexOf(this[i]) == i) n.push(this[i]);
}
return n;
}
HTTP狀態(tài)碼
100 ?Continue繼續(xù),一般在發(fā)送post請(qǐng)求時(shí),已發(fā)送了http header之后服務(wù)端將返回此信息,表示確認(rèn),之后發(fā)送具體參數(shù)信息
200 ?OK正常返回信息
201 ?Created請(qǐng)求成功并且服務(wù)器創(chuàng)建了新的資源
202 ?Accepted服務(wù)器已接受請(qǐng)求,但尚未處理
301 ?Moved Permanently請(qǐng)求的網(wǎng)頁已永久移動(dòng)到新位置。
302 Found臨時(shí)性重定向。
303 See Other臨時(shí)性重定向,且總是使用GET請(qǐng)求新的URI。
304 ?Not Modified自從上次請(qǐng)求后,請(qǐng)求的網(wǎng)頁未修改過。
400 Bad Request服務(wù)器無法理解請(qǐng)求的格式,客戶端不應(yīng)當(dāng)嘗試再次使用相同的內(nèi)容發(fā)起請(qǐng)求。
401 Unauthorized請(qǐng)求未授權(quán)。
403 Forbidden禁止訪問。
404 Not Found找不到如何與URI相匹配的資源。
500 Internal Server Error最常見的服務(wù)器端錯(cuò)誤。
503 Service Unavailable服務(wù)器端暫時(shí)無法處理請(qǐng)求(可能是過載或維護(hù))。
js操作獲取和設(shè)置cookie
//創(chuàng)建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 += '; expires=' + expires;
}
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);
}
說說TCP傳輸?shù)娜挝帐植呗?/p>
為了準(zhǔn)確無誤地把數(shù)據(jù)送達(dá)目標(biāo)處,TCP協(xié)議采用了三次握手策略。用TCP協(xié)議把數(shù)據(jù)包送出去后,TCP不會(huì)對(duì)傳送 ?后的情況置之不理,它一定會(huì)向?qū)Ψ酱_認(rèn)是否成功送達(dá)。握手過程中使用了TCP的標(biāo)志:SYN和ACK。
發(fā)送端首先發(fā)送一個(gè)帶SYN標(biāo)志的數(shù)據(jù)包給對(duì)方。接收端收到后,回傳一個(gè)帶有SYN/ACK標(biāo)志的數(shù)據(jù)包以示傳達(dá)確認(rèn)信息。最后,發(fā)送端再回傳一個(gè)帶ACK標(biāo)志的數(shù)據(jù)包,代表“握手”結(jié)束
若在握手過程中某個(gè)階段莫名中斷,TCP協(xié)議會(huì)再次以相同的順序發(fā)送相同的數(shù)據(jù)包。
說說你對(duì)Promise的理解
依照Promise/A+的定義,Promise有四種狀態(tài):
pending:初始狀態(tài),非fulfilled或rejected.
fulfilled:成功的操作.
rejected:失敗的操作.
settled: Promise已被fulfilled或rejected,且不是pending
另外,fulfilled與rejected一起合稱settled。
Promise對(duì)象用來進(jìn)行延遲(deferred)和異步(asynchronous )計(jì)算。
Promise的構(gòu)造函數(shù)
構(gòu)造一個(gè)Promise,最基本的用法如下:
var promise = new Promise(function(resolve, reject) {
if (...) { ?// succeed
resolve(result);
} else { ? // fails
reject(Error(errMessage));
}
});
Promise實(shí)例擁有then方法(具有then方法的對(duì)象,通常被稱為thenable)。它的使用方法如下:
promise.then(onFulfilled, onRejected)
接收兩個(gè)函數(shù)作為參數(shù),一個(gè)在fulfilled的時(shí)候被調(diào)用,一個(gè)在rejected的時(shí)候被調(diào)用,接收參數(shù)就是future,onFulfilled對(duì)應(yīng)resolve, onRejected對(duì)應(yīng)reject。
Javascript垃圾回收方法
標(biāo)記清除(mark and sweep)
這是JavaScript最常見的垃圾回收方式,當(dāng)變量進(jìn)入執(zhí)行環(huán)境的時(shí)候,比如函數(shù)中聲明一個(gè)變量,垃圾回收器將其標(biāo)記為“進(jìn)入環(huán)境”,當(dāng)變量離開環(huán)境的時(shí)候(函數(shù)執(zhí)行結(jié)束)將其標(biāo)記為“離開環(huán)境”。
垃圾回收器會(huì)在運(yùn)行的時(shí)候給存儲(chǔ)在內(nèi)存中的所有變量加上標(biāo)記,然后去掉環(huán)境中的變量以及被環(huán)境中變量所引用的變量(閉包),在這些完成之后仍存在標(biāo)記的就是要?jiǎng)h除的變量了
引用計(jì)數(shù)(reference counting)
在低版本IE中經(jīng)常會(huì)出現(xiàn)內(nèi)存泄露,很多時(shí)候就是因?yàn)槠洳捎靡糜?jì)數(shù)方式進(jìn)行垃圾回收。引用計(jì)數(shù)的策略是跟蹤記錄每個(gè)值被使用的次數(shù),當(dāng)聲明了一個(gè) 變量并將一個(gè)引用類型賦值給該變量的時(shí)候這個(gè)值的引用次數(shù)就加1,如果該變量的值變成了另外一個(gè),則這個(gè)值得引用次數(shù)減1,當(dāng)這個(gè)值的引用次數(shù)變?yōu)?的時(shí)候,說明沒有變量在使用,這個(gè)值沒法被訪問了,因此可以將其占用的空間回收,這樣垃圾回收器會(huì)在運(yùn)行的時(shí)候清理掉引用次數(shù)為0的值占用的空間。
在IE中雖然JavaScript對(duì)象通過標(biāo)記清除的方式進(jìn)行垃圾回收,但BOM與DOM對(duì)象卻是通過引用計(jì)數(shù)回收垃圾的,也就是說只要涉及BOM及DOM就會(huì)出現(xiàn)循環(huán)引用問題。
談?wù)勑阅軆?yōu)化問題
代碼層面:避免使用css表達(dá)式,避免使用高級(jí)選擇器,通配選擇器。 緩存利用:緩存Ajax,使用CDN,使用外部js和css文件以便緩存,添加Expires頭,服務(wù)端配置Etag,減少DNS查找等 請(qǐng)求數(shù)量:合并樣式和腳本,使用css圖片精靈,初始首屏之外的圖片資源按需加載,靜態(tài)資源延遲加載。 請(qǐng)求帶寬:壓縮文件,開啟GZIP,
移動(dòng)端性能優(yōu)化
盡量使用css3動(dòng)畫,開啟硬件加速。適當(dāng)使用touch事件代替click事件。避免使用css3漸變陰影效果。 盡可能少的使用box-shadow與gradients。box-shadow與gradients往往都是頁面的性能殺手
什么是Etag?
瀏覽器下載組件的時(shí)候,會(huì)將它們存儲(chǔ)到瀏覽器緩存中。如果需要再次獲取相同的組件,瀏覽器將檢查組件的緩存時(shí)間,假如已經(jīng)過期,那么瀏覽器將發(fā)送一個(gè)條件GET請(qǐng)求到服務(wù)器,服務(wù)器判斷緩存還有效,則發(fā)送一個(gè)304響應(yīng), 告訴瀏覽器可以重用緩存組件。
那么服務(wù)器是根據(jù)什么判斷緩存是否還有效呢?答案有兩種方式,一種是前面提到的ETag,另一種是根據(jù)Last-Modified
Expires和Cache-Control
Expires要求客戶端和服務(wù)端的時(shí)鐘嚴(yán)格同步。HTTP1.1引入Cache-Control來克服Expires頭的限制。如果max-age和Expires同時(shí)出現(xiàn),則max-age有更高的優(yōu)先級(jí)。
Cache-Control: no-cache, private, max-age=0
ETag: abcde
Expires: Thu, 15 Apr 2014 20:00:00 GMT
Pragma: private
Last-Modified: $now // RFC1123 format
棧和隊(duì)列的區(qū)別?
棧的插入和刪除操作都是在一端進(jìn)行的,而隊(duì)列的操作卻是在兩端進(jìn)行的。
隊(duì)列先進(jìn)先出,棧先進(jìn)后出。
棧只允許在表尾一端進(jìn)行插入和刪除,而隊(duì)列只允許在表尾一端進(jìn)行插入,在表頭一端進(jìn)行刪除
棧和堆的區(qū)別?
棧區(qū)(stack)—由編譯器自動(dòng)分配釋放 ??,存放函數(shù)的參數(shù)值,局部變量的值等。
堆區(qū)(heap)—一般由程序員分配釋放, ??若程序員不釋放,程序結(jié)束時(shí)可能由OS回收。
堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹,如:堆排序;
棧(數(shù)據(jù)結(jié)構(gòu)):一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)。
關(guān)于Http 2.0你知道多少?
HTTP/2引入了“服務(wù)端推(serverpush)”的概念,它允許服務(wù)端在客戶端需要數(shù)據(jù)之前就主動(dòng)地將數(shù)據(jù)發(fā)送到客戶端緩存中,從而提高性能。HTTP/2提供更多的加密支持HTTP/2使用多路技術(shù),允許多個(gè)消息在一個(gè)連接上同時(shí)交差。 它增加了頭壓縮(header compression),因此即使非常小的請(qǐng)求,其請(qǐng)求和響應(yīng)的header都只會(huì)占用很小比例的帶寬。