百度前端面試總結

  1. 跨域問題:

5大方法:javascript

(1)     CORS(cross origin resources sharing跨域資源共享):ajax請求採用絕對路徑,在服務器端設置Access-Control-Allow-Origin來進行。php

(2)     JSONP: 主要採用的是js的引入能夠跨域共享,經過callback來載入其餘域的資源,形式是:callback({數據名:數據值}),可是須要後臺支持,而且只支持get方式,但基本沒有兼容問題,老瀏覽器也很支持css

(3)     window.domain:經過在兩個頁面中設置相同的window.domain,可是window.domain只能設置成自身或者更高一級的父域,因此只能解決的是不一樣子域的問題,也就是主域必定要相同。html

(4)     window.name: 在一個窗口(window)的生命週期中,窗口載入的全部的頁面都是共享一個window.name。(不是很理解跟跨域有什麼關係)前端

(5)     window.postMessage(message,targetOrigin)(HTML5的方法:IE8+,FireFox.Chrome,Opera等):能夠用這個向其餘的window對象發送消息,不管這個window對象是否屬於同源或不一樣源。html5

答:什麼是跨域?java

概念:只要協議、域名、端口有任何一個不一樣,都被看成是不一樣的域。jquery

URL                      說明       是否容許通訊面試

http://www.a.com/a.jsajax

http://www.a.com/b.js     同一域名下   容許

http://www.a.com/lab/a.js

http://www.a.com/script/b.js 同一域名下不一樣文件夾 容許

http://www.a.com:8000/a.js

http://www.a.com/b.js     同一域名,不一樣端口  不容許

http://www.a.com/a.js

https://www.a.com/b.js 同一域名,不一樣協議 不容許

http://www.a.com/a.js

http://70.32.92.74/b.js 域名和域名對應ip 不容許

http://www.a.com/a.js

http://script.a.com/b.js 主域相同,子域不一樣 不容許

http://www.a.com/a.js

http://a.com/b.js 同一域名,不一樣二級域名(同上) 不容許(cookie這種狀況下也不容許訪問)

http://www.cnblogs.com/a.js

http://www.a.com/b.js 不一樣域名 不容許

對於端口和協議的不一樣,只能經過後臺來解決。

跨域資源共享(CORS

CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS背後的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功仍是失敗。

<script type="text/javascript">

    var xhr = new XMLHttpRequest();

    xhr.open("GET", "/trigkit4",true);

    xhr.send();

</script>

以上的trigkit4是相對路徑,若是咱們要使用CORS,相關Ajax代碼可能以下所示:

<script type="text/javascript">

    var xhr = new XMLHttpRequest();

    xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true);

    xhr.send();

</script>

代碼與以前的區別就在於相對路徑換成了其餘域的絕對路徑,也就是你要跨域訪問的接口地址。

服務器端對於CORS的支持,主要就是經過設置Access-Control-Allow-Origin來進行的。若是瀏覽器檢測到相應的設置,就能夠容許Ajax進行跨域的訪問。


要解決跨域的問題,咱們可使用如下幾種方法:

經過jsonp跨域

如今問題來了?什麼是jsonp?維基百科的定義是:JSONP(JSON with Padding)是資料格式 JSON 的一種「使用模式」,可讓網頁從別的網域要資料。

JSONP也叫填充式JSON,是應用JSON的一種新方法,只不過是被包含在函數調用中的JSON,例如:

callback({"name","trigkit4"});

JSONP由兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面中調用的函數,而數據就是傳入回調函數中的JSON數據。

在js中,咱們直接用XMLHttpRequest請求不一樣域上的數據時,是不能夠的。可是,在頁面上引入不一樣域上的js腳本文件倒是能夠的,jsonp正是利用這個特性來實現的。 例如:

<script type="text/javascript">

    function dosomething(jsondata){

        //處理得到的json數據

    }

</script>

<script src="http://example.com/data.php?callback=dosomething"></script>

js文件載入成功後會執行咱們在url參數中指定的函數,而且會把咱們須要的json數據做爲參數傳入。因此jsonp是須要服務器端的頁面進行相應的配合的。

<?php

$callback = $_GET['callback'];//獲得回調函數名

$data = array('a','b','c');//要返回的數據

echo $callback.'('.json_encode($data).')';//輸出

?>

最終,輸出結果爲:dosomething(['a','b','c']);

若是你的頁面使用jquery,那麼經過它封裝的方法就能很方便的來進行jsonp操做了。

<script type="text/javascript">

    $.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){

        //處理得到的json數據

    });

</script>

jquery會自動生成一個全局函數來替換callback=?中的問號,以後獲取到數據後又會自動銷燬,實際上就是起一個臨時代理函數的做用。$.getJSON方法會自動判斷是否跨域,不跨域的話,就調用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調用jsonp的回調函數。

JSONP的優缺點

JSONP的優勢是:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中均可以運行,不須要XMLHttpRequest或ActiveX的支持;而且在請求完畢後能夠經過調用callback的方式回傳結果。

JSONP的缺點則是:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種狀況,不能解決不一樣域的兩個頁面之間如何進行JavaScript調用的問題。

CORSJSONP對比

CORS與JSONP相比,無疑更爲先進、方便和可靠。

    一、 JSONP只能實現GET請求,而CORS支持全部類型的HTTP請求。

 

    二、 使用CORS,開發者可使用普通的XMLHttpRequest發起請求和得到數據,比起JSONP有更好的錯誤處理。

 

    三、 JSONP主要被老的瀏覽器支持,它們每每不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS)。

經過修改document.domain來跨子域

瀏覽器都有一個同源策略,其限制之一就是第一種方法中咱們說的不能經過ajax的方法去請求不一樣源中的文檔。 它的第二個限制是瀏覽器中不一樣域的框架之間是不能進行js的交互操做的。
不一樣的框架之間是能夠獲取window對象的,但卻沒法獲取相應的屬性和方法。好比,有一個頁面,它的地址是http://www.example.com/a.html , 在這個頁面裏面有一個iframe,它的src是http://example.com/b.html, 很顯然,這個頁面與它裏面的iframe框架是不一樣域的,因此咱們是沒法經過在頁面中書寫js代碼來獲取iframe中的東西的:

<script type="text/javascript">

    function test(){

        var iframe = document.getElementById('ifame');

        var win = document.contentWindow;//能夠獲取到iframe裏的window對象,但該window對象的屬性和方法幾乎是不可用的

        var doc = win.document;//這裏獲取不到iframe裏的document對象

        var name = win.name;//這裏一樣獲取不到window對象的name屬性

    }

</script>

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

這個時候,document.domain就能夠派上用場了,咱們只要把http://www.example.com/a.html 和http://example.com/b.html這兩個頁面的document.domain都設成相同的域名就能夠了。但要注意的是,document.domain的設置是有限制的,咱們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。

1.在頁面 http://www.example.com/a.html 中設置document.domain:

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

<script type="text/javascript">

    document.domain = 'example.com';//設置成主域

    function test(){

        alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 對象

    }

</script>

2.在頁面 http://example.com/b.html 中也設置document.domain:

<script type="text/javascript">

    document.domain = 'example.com';//在iframe載入這個頁面也設置document.domain,使之與主頁面的document.domain相同

</script>

修改document.domain的方法只適用於不一樣子域的框架間的交互。

使用window.name來進行跨域

window對象有個name屬性,該屬性有個特徵:即在一個窗口(window)的生命週期內,窗口載入的全部的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的全部頁面中的

使用HTML5window.postMessage方法跨域

window.postMessage(message,targetOrigin) 方法是html5新引進的特性,可使用它來向其它的window對象發送消息,不管這個window對象是屬於同源或不一樣源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支持window.postMessage方法。

  1. 塊狀元素,內聯元素,顯示上的區別和舉例有哪些元素?

答:

塊狀元素
通常是其餘元素的容器,可容納內聯元素和其餘塊狀元素,塊狀元素排斥其餘元素與其位於同一行,寬度(width)高度(height)起做用。常見塊狀元素爲div和p、h1~h6,hr,pre,table、ul、ol、li等

內聯元素

內聯元素不能設置寬高,豎直方向上不能設置marginpadding。但水平方向上能夠設置marginpadding
內聯元素只能容納文本或者其餘內聯元素,它容許其餘內聯元素與其位於同一行,但寬度(width)高度(height)不起做用。常見內聯元素爲「a」、big、em、span、strong、img、textarea、label、input等

 

  1. 塊狀元素的水平、垂直居中顯示如何實現?

答: 讓div內的內容(包括文字及圖片)垂直居中: vertical-align的值是middle,水平居中:center.

關於居中使用css爲:position:fixed;left:50%;top:50%;margin-left:width/2;

margin-top:height/2; 對於ie6,只能把position:改爲absolute;(在其餘瀏覽器換成absolute也沒什麼問題,由於fixed與absolute定位元素是同樣的)

 

  1. Position

答:position:absolute和float會隱式地改變display類型,不論以前什麼類型的元素(display:none除外),只要設置了position:absolute、float:left或float:right中任意一個,都會讓元素以display:inline-block的方式顯示。

 

  1. cmd和amd模塊化,requirejs等。。還有MVC模式

答 :

1.對於依賴的模塊,AMD 是提早執行,CMD 是延遲執行。不過 RequireJS 從 2.0 開始,也改爲能夠延遲執行(根據寫法不一樣,處理方式不一樣)。CMD 推崇 as lazy as possible.

2. CMD 推崇依賴就近,AMD 推崇依賴前置。

3. AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。好比 AMD 裏,require 分全局 require 和局部 require都叫 require。CMD 裏,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啓動。CMD 裏,每一個 API 都簡單純粹。

 

 

  1. 變量聲明提早

答:

javascript的變量聲明具備hoisting機制,JavaScript引擎在執行的時候,會把全部變量的聲明都提高到當前做用域的最前面。

先看一段代碼

1

2

3

4

5

var v = "hello";

(function(){

  console.log(v);

  var v = "world";

})();

這段代碼運行的結果是什麼呢?
答案是:undefined
這段代碼說明了兩個問題,
第一,function做用域裏的變量v遮蓋了上層做用域變量v。代碼作少些變更

1

2

3

4

5

var v = "hello";

if(true){

  console.log(v);

  var v = "world";

}

輸出結果爲"hello",說明javascript是沒有塊級做用域的函數是JavaScript中惟一擁有自身做用域的結構。

第二,在function做用域內,變量v的聲明被提高了。因此最初的代碼至關於:

1

2

3

4

5

6

var v = "hello";

(function(){

  var v; //declaration hoisting

  console.log(v);

  v = "world";

})();

聲明、定義與初始化

聲明宣稱一個名字的存在,定義則爲這個名字分配存儲空間,而初始化則是爲名字分配的存儲空間賦初值。
用C++來表述這三個概念

1

2

3

extern int i;//這是聲明,代表名字i在某處已經存在了

int i;//這是聲明並定義名字i,爲i分配存儲空間

i = 0;//這是初始化名字i,爲其賦初值爲0

javascript中則是這樣

1

2

var v;//聲明變量v

v = "hello";//(定義並)初始化變量v

由於javascript爲動態語言,其變量並無固定的類型,其存儲空間大小會隨初始化與賦值而變化,因此其變量的「定義」就不像傳統的靜態語言同樣了,其定義顯得可有可無。

聲明提高

當前做用域內的聲明都會提高到做用域的最前面,包括變量和函數的聲明

1

2

3

4

5

6

(function(){

  var a = "1";

  var f = function(){};

  var b = "2";

  var c = "3";

})();

變量a,f,b,c的聲明會被提高到函數做用域的最前面,相似以下:

1

2

3

4

5

6

7

(function(){

  var a,f,b,c;

  a = "1";

  f = function(){};

  b = "2";

  c = "3";

})();

請注意函數表達式並無被提高,這也是函數表達式與函數聲明的區別。進一步看兩者的區別:

1

2

3

4

5

6

7

8

9

(function(){

  //var f1,function f2(){}; //hoisting,被隱式提高的聲明

 

  f1(); //ReferenceError: f1 is not defined

  f2();

 

  var f1 = function(){};

  function f2(){}

})();

上面代碼中函數聲明f2被提高,因此在前面調用f2是沒問題的。雖然變量f1也被提高,但f1提高後的值爲undefined,其真正的初始值是在執行到函數表達式處被賦予的。因此只有聲明是被提高的。

名字解析順序

javascript中一個名字(name)以四種方式進入做用域(scope),其優先級順序以下:
一、語言內置:全部的做用域中都有 this 和 arguments 關鍵字
二、形式參數:函數的參數在函數做用域中都是有效的
三、函數聲明:形如function foo() {}
四、變量聲明:形如var bar;

名字聲明的優先級如上所示,也就是說若是一個變量的名字與函數的名字相同,那麼函數的名字會覆蓋變量的名字,不管其在代碼中的順序如何。但名字的初始化倒是按其在代碼中書寫的順序進行的,不受以上優先級的影響。看代碼:

1

2

3

4

5

6

7

8

9

(function(){

    var foo;

    console.log(typeof foo); //function

     

    function foo(){}

 

    foo = "foo";

    console.log(typeof foo); //string

})();

若是形式參數中有多個同名變量,那麼最後一個同名參數會覆蓋其餘同名參數,即便最後一個同名參數並無定義。

以上的名字解析優先級存在例外,好比能夠覆蓋語言內置的名字arguments。

命名函數表達式

能夠像函數聲明同樣爲函數表達式指定一個名字,但這並不會使函數表達式成爲函數聲明。命名函數表達式的名字不會進入名字空間,也不會被提高。

1

2

3

4

5

f();//TypeError: f is not a function

foo();//ReferenceError: foo is not defined

var f = function foo(){console.log(typeof foo);};

f();//function

foo();//ReferenceError: foo is not defined

命名函數表達式的名字只在該函數的做用域內部有效。

 

  1. 數組去重(看來是百度的常見問題,在其餘人的總結中看到了答案)

答:方法一:(這個方法經過兩層嵌套,實現查找,效率較低。整體思路是把數組元素逐個搬運到另外一個數組,搬運的過程當中檢查這個元素是否有重複,若是有就直接丟掉。)

function unique(arr) {

    var result = [], isRepeated;

    for (var i = 0, len = arr.length; i < len; i++) {

        isRepeated = false;

        for (var j = 0, len = result.length; j < len; j++) {

            if (arr[i] == result[j]) {  

                isRepeated = true;

                break;

            }

        }

        if (!isRepeated) {

            result.push(arr[i]);

        }

    }

    return result;

}

方法二:(這個方法是利用hash表中(的key值存不存在的方法實現,也能夠說是map、reduce的方法))

function unique(arr) {

    var result = [], hash = {};

    for (var i = 0, elem; (elem = arr[i]) != null; i++) {

        if (!hash[elem]) {

            result.push(elem);

            hash[elem] = true;

        }

    }

    return result;

//http://www.cnblogs.com/sosoft/

}

 

 

  1. Jquery的defered實現原理
  2. 繼承
  3. 除去字符串中的空格

答:1.s.replace(" ","");      

2.text.replace(/\s/ig,'');

 

  1. 閉包

答:閉包的形式是function a中return function b,b中會用到a 中的局部變量,也可能用到函數a的外部變量,根據js內存回收機制,一旦function a執行完成,a中定義的局部變量就會被回收清除,採用閉包之後就會將function b所用到的全部變量跟b綁在一塊兒,只要function b不被清除,這些變量就不會被回收和清除。閉包容易產生內存泄露,要注意在不用b時,手動的清除b。

(實際上任何函數都是全局做用域的內部函數,都能訪問全局變量,因此都是window的閉包) 

閉包的用處:閉包能夠將函數中的局部變量給以保存下來,做用:

  1. 匿名函數自執行(並且這種機制不會污染對象)
  2. 緩存,再來看一個例子,設想咱們有一個處理過程很耗時的函數對象,每次調用都會花費很長時間,
    那麼咱們就須要將計算出來的值存儲起來,當調用這個函數的時候,首先在緩存中查找,若是找不到,則進行計算,
    而後更新緩存並返回值,若是找到了,直接返回查找到的值便可。閉包正是能夠作到這一點,由於它不會釋放外部的引用,
    從而函數內部的值能夠得以保留。
  3. 實現封裝
  4. 閉包的另外一個重要用途是實現面向對象中的對象,傳統的對象語言都提供類的模板機制,
    這樣不一樣的對象(類的實例)擁有獨立的成員及狀態,互不干涉。雖然JavaScript中沒有類這樣的機制,可是經過使用閉包,
    咱們能夠模擬出這樣的機制。

 

  1. 前端優化

答:答案同網易面試題

  1. css文件引入的方法,import和link方法的區別
1link@import2link@import3link4link@import答:()屬於HTML標籤,而是CSS提供的; 
  ()頁面被加載的時,會同時被加載,而引用的CSS會等到頁面被加載完再加載;
  () import只在IE5以上才能識別,而是HTML標籤,無兼容問題;
  ()方式的樣式的權重高於的權重.

答:有4種,分別是行內式、內嵌式、連接式和導入式。

  1. 行內式:直接在html標籤中用style設定css
  2. 嵌入式:採用<style>標籤,  缺點是對於一個包含不少網頁的網站,在每一個網頁中使用嵌入式,進行修改樣式時很是麻煩。單一網頁能夠考慮使用嵌入式

3.導入式: 將一個獨立的.css文件引入HTML文件中,導入式使用CSS規則引入外部CSS文件,<style>標記也是寫在<head>標記中,使用的語法以下:

          <style type="text/css">

                    @import"mystyle.css"; 此處要注意.css文件的路徑

         </style>

缺陷:  導入式會在整個網頁裝載完後再裝載CSS文件,所以這就致使了一個問題,若是網頁比較大則會兒出現先顯示無樣式的頁面,閃爍一下以後,再出現網頁的樣式。這是導入式固有的一個缺陷。

4.連接式: 也是將一個.css文件引入到HTML文件中,但它與導入式不一樣的是連接式使用HTML規則引入外部CSS文件,它在網頁的<head></head>標籤對中使用<link>標記來引入外部樣式表文件,使用語法以下:

          <link href="mystyle.css" rel="stylesheet" type="text/css"/>

          使用連接式時與導入式不一樣的是它會以網頁文件主體裝載前裝載CSS文件,所以顯示出來的網頁從一開始就是帶樣式的效果的,它不會象導入式那樣先顯示無樣式的網頁,而後再顯示有樣式的網頁,這是連接式的優勢。

總結:通常來講,作網站時把樣式多寫在多個樣式表文件中,所以咱們先用連接式引入一個總的CSS文件,而後在這個CSS文件中在使用導入式來引入其餘的CSS文件。但若是經過JavaScrip來動態引入CSS文件則只能使用連接式。

 

  1. 事件冒泡及其應用

答:事件發生的順序是:先是事件捕獲階段:根節點逐級送到子節點。

而後是冒泡過程是:子節點到根節點往下冒。

應用是事件代理。事件代理好處:減小事件綁定的對象的內存。

 

其餘人補充:

  1. 淘寶爲什麼將圖片放在另外一個域中,實現跨域加載?

答:對於這道題,我是這麼想的:不一樣的域名通過dns(域名解析系統)解析之後,映射到的是不一樣的ip地址,不一樣的ip地址對應的就是不一樣的服務器存儲地址,因此淘寶將圖片放在另外一個域中,主要考慮的應該是服務的存儲方面。並且將圖片放在其餘服務器上,減小主服務的存儲壓力,能夠減小IO口的壓力,加快速度。

 

  1. display的幾種方式,具體區別?

 

答: 主要說一下display爲inline-block和display爲inline-table的區別,

這是別人的測試成果:(原文地址:http://blog.csdn.net/yenange/article/details/7520789)

 

  IE6/7(IE_Test) IE8(xp/2003) IE9 Chrome 18.0.1025.162 m Firefox 12.0
inline X
inline-block X ?
inline-table X

   

 該博主得出的結論是:

因此在通常狀況下, 但願並排, 最好是用 inline ,  判斷一下是Chrome則用 inline-table

var display= navigator.userAgent.indexOf("Chrome") > -1 ? "inline-table" : "inline";

我以爲inline-block和inline-table最大的區別是都是行內塊級元素,(具體差異下次再整理,找不到好的博文)

相關文章
相關標籤/搜索