天天刷Web面試題(前10天彙總)

1、算法題部分javascript

 

1. 如何獲取瀏覽器URL中查詢字符串中的參數?

function getParamsWithUrl(url) {    
  var args = url.split('?');  
  if (args[0] === url) {        
       return "";    }    
    var arr = args[1].split('&');    
    var obj = {};    
    for ( var i = 0;
     i < arr.length; i++)
     {        
       var arg = arr[i].split('=');        obj[arg[0]] = arg[1];    }    
    return obj; }
 
var href = getParamsWithUrl
('http://www.itlike.com?id=1022&name=撩課&age=1'); console.log(href['name']); // 撩課

2. 寫一個深度克隆方法(es5)?

/** *  深拷貝 * @param {object}fromObj 拷貝的對象 * @param {object}toObj  目標對象 */
function deepCopyObj2NewObj(fromObj, toObj) {  
  for(var key in fromObj){      
    // 1. 取出鍵值對     var fromValue = fromObj[key];      
    // 2. 檢查當前的屬性值是什麼類型     // 若是是值類型,那麼就直接拷貝賦值     if(!isObj(fromValue)){       toObj[key] = fromValue;     }else {          
       // 若是是引用類型,        // 那麼就再調用一次這個方法,        // 去內部拷貝這個對象的全部屬性        var tempObj =
       new fromValue.constructor;        console.log(fromValue.constructor);        deepCopyObj2NewObj(fromValue, tempObj);        toObj[key] = tempObj;     }   } }

/** * 輔助函數, 判斷是不是對象 * @param {object}obj * @returns {boolean} */
function isObj(obj) {  
   return obj instanceof Object; }

3. 對數組[1,2,3,8,2,8]進行去重,es5或者es6方法?

es5四種方式:
方式一:
Array.prototype.unique1 = function() {    
   // 1. 定義數組    var temp = [];    
   // 2. 遍歷當前數組    for(var i = 0;
      i < this.length; i++) {        
       // 3.若是當前數組的第i
       // 已經保存進了臨時數組,        // 那麼跳過,不然把當前項
       // push到臨時數組裏面        if (-1 === temp.indexOf(this[i]))
       {           temp.push(this[i]);        }    }    
   return temp; }; 方式二:
Array.prototype.unique2 = function() {    
   //1. hash爲hash表,r爲臨時數組    var hash = {}, temp=[];    
   // 2.遍歷當前數組    for(var i = 0; i < this.length; i++)    {        
       // 3. 若是hash表中沒有當前項        if (!hash[this[i]])        {            
           // 4.存入hash表            hash[this[i]] = true;            
           // 5.把當前數組的當前項            // push到臨時數組裏面            temp.push(this[i]);        }    }    
   return temp; }; 方式三:
Array.prototype.unique3 = function() {    
   var n = [this[0]];    
   for(var i = 1;
       i < this.length; i++){        
      if (this.indexOf(this[i]) === i) {            n.push(this[i]);        }    }    
   return n; }; 方式四:
Array.prototype.unique4 = function() {    
   this.sort();    
   var re=[this[0]];    
   for(var i = 1;
       i < this.length; i++) {        
    if( this[i] !== re[re.length-1]){        re.push(this[i]);     }    }    
   return re; }; es6實現方式:
Array.prototype.unique =
Array.prototype.unique ||
() =>{    
   return [...new Set(this)]; };

4. 如何判斷一個對象是否爲數組?

function isArray(arg) {    
  if (typeof arg === 'object') {        
      return 
      Object.prototype.toString.call(arg)
      === '[object Array]';    }  
   return false; }

5. 冒泡排序?

思路:
每次比較相鄰的兩個數,
若是後一個比前一個小,換位置;

var arr = [2, 0, 1, 9, 8, 7, 3];
function bubbleSort(arr) {  
  for (var i = 0;
       i < arr.length - 1; i++) {
     for(var j = 0;
         j < arr.l    i - 1; j++) {
        if(arr[j + 1] < arr[j]) {
           var temp;            temp = arr[j];            arr[j] = arr[j + 1];            arr[j + 1] = temp;         }       }   }
 return arr; }
console.log(bubbleSort(arr));

6. 快速排序?

思路: 採用二分法,取出中間數,
數組每次和中間數比較,
小的放到左邊,大的放到右邊;

var arr = [2, 0, 1, 9, 8, 7, 3];
function quickSort(arr) {
   if(arr.length == 0) {
      // 返回空數組
      return [];        }
   var cIndex = Math.floor(arr.length / 2);    
   var c = arr.splice(cIndex, 1);    
   var l = [];    
   var r = [];
   for (var i = 0;
        i < arr.length;
        i++) { 
     if(arr[i] < c) {         l.push(arr[i]);      } else {         r.push(arr[i]);      }    }    
   return quickSort(l).concat(c, quickSort(r)); }
console.log(quickSort(arr));

7. 正則表達式驗證郵箱格式?

var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
var email = "yjh@itlike.com";
console.log(reg.test(email));  // true  

8. 正則表達式清除字符串先後的空格?

function trim(str) {
   if (str && typeof str === "string")
   {        
       // 去除先後空白符        return
       str.replace(/(^\s*)|(\s*)$/g,"");    } }

 

---華麗分割線---css

 

 

2、JS系列部分html

 

1. var的變量提高的底層原理是什麼?

JS引擎的工做方式是:
1) 先解析代碼,獲取全部被聲明的變量;
2) 而後在運行。也就是說分爲預處理和執行兩個階段。
補充: 變量提高:全部變量的聲明語句都會被提高到代碼頭部。 可是變量提高只對var命令聲明的變量有效,若是一個變量不是 用var命令聲明的,就不會發生變量提高。 js裏的function也可看作變量,也存在變量提高狀況。

2. JS如何計算瀏覽器的渲染時間?

瀏覽器的渲染過程主要包括如下幾步:
1) 解析HTML生成DOM樹。
2) 解析CSS生成CSSOM規則樹。
3) 將DOM樹與CSSOM規則樹合併在一塊兒生成渲染樹。
4) 遍歷渲染樹開始佈局,計算每一個節點的位置大小信息。
5) 將渲染樹每一個節點繪製到屏幕。

優化考慮:
CSS 優先:引入順序上,CSS 資源先於 JavaScript 資源。
JS置後:一般把JS代碼放到頁面底部,且JavaScript 應儘可能少影響 DOM 的構建。

3. JS的回收機制?

垃圾回收機制就是間歇的不按期的尋找到再也不使用的變量,
並釋放掉它們所指向的內存; 主要爲了以防內存泄漏,
(內存泄漏: 當已經不須要某塊內存時這塊內存還存在着), 

JS有兩種變量: 全局變量和在函數中產生的局部變量。
局部變量的生命週期在函數執行事後就結束了,
此時即可將它引用的內存釋放(即垃圾回收); 
但全局變量生命週期會持續到瀏覽器關閉頁面。

JS執行環境中的垃圾回收器有兩種方式:
標記清除(mark and sweep)、 引用計數(reference counting)。 標記清除:  垃圾收集器給內存中的全部變量都加上標記, 而後去掉環境中的變量以及被環境中的變量引用的變量的標記。 在此以後再被加上的標記的變量即爲須要回收的變量, 由於環境中的變量已經沒法訪問到這些變量。 引用計數(reference counting):  這種方式經常會引發內存泄漏, 低版本的IE使用這種方式。機制就是跟蹤一個值的引用次數, 當聲明一個變量並將一個引用類型賦值給該變量時該值引用次數加1, 當這個變量指向其餘一個時該值的引用次數便減一。 當該值引用次數爲0時就會被回收。

4. 寫一下節點增刪改?

//  注意:動態建立元素不會直接顯示在頁面當中,
// 前面必須是document,不能是其餘
1)document.createElement(標籤名); // 在指定父級子節點最後一個後面追加子元素
2)父級.appendChild(要追加的元素) ;   // 在父級的指定子元素前面插入一個新元素
(注意:先判斷若是第二個參數的節點是否存在)
3)父級.insertBefore(新的元素,指定的已有子元素); // 深克隆(負值標籤、標籤屬性、標籤裏面內容);
// 淺克隆(負值標籤、標籤屬性不復制標籤裏面內容)
4)元素.cloneNode(true) 或者元素.cloneNode(false);
5)父級.removeChild(已有子元素);
6)父級.replaceChild(新的元素節點,原有元素節點);

5. 如何獲取元素的父節點和兄弟節點,寫一下?

獲取父節點:
// 1. parentNode獲取父節點
// 獲取的是當前元素的直接父元素。
var p = document.getElementById("test").parentNode;

// 2. parentElement獲取父節點
// parentElement和parentNode同樣,
只是parentElement是ie的標準。
var p1 = document.getElementById("test").parentElement;

// 3. offsetParent獲取全部父節點
var p2 = document.getElementById("test").offsetParent; 獲取兄弟節點:
// 1. 經過獲取父親節點再獲取子節點來獲取兄弟節點
var brother1 = document.getElementById("test").parentNode.children[1];

// 2. 獲取上一個兄弟節點
// 在獲取前一個兄弟節點的時候可使用previousSibling
// 和previousElementSibling。
// 他們的區別是previousSibling會匹配字符,
// 包括換行和空格,而不是節點。
// previousElementSibling則直接匹配節點。
var brother2 = document.getElementById("test").previousElementSibling;
var brother3 = document.getElementById("test").previousSibling;

// 3. 獲取下一個兄弟節點
var brother4 = document.getElementById("test").nextElementSibling;
var brother5 = document.getElementById("test").nextSibling;

6. 給你一個亂序數組,你怎麼排序?

撩課小編:  sort, 冒泡, 選擇, 二分法....

7. 原生JS都有哪些方式能夠實現兩個頁面間的通訊?

1)  經過url地址欄傳遞參數;
    例如:點擊列表頁中的每一條數據,
    咱們跳轉到同一個詳細頁面,
    可是根據點擊的不同能夠看到
    不一樣的內容,這樣的話咱們就能夠
    在URL中傳遞不一樣的值來區分了;

2)  經過本地存儲 cookie、localeStorage、
    sessionStroage...,例如:京東的登陸,
    咱們在登陸頁登陸完成後,
    把用戶信息存儲到本地,
    而後在其它頁面中若是須要使用的話,
    咱們直接從本地的存儲數據中拿
    出來用便可;

3)  使用iframe在A頁面中嵌入B頁面,
    這樣的話,在A中能夠經過一些屬性
    和方法實現和B頁面的通訊;

4)  利用postMessage實現頁面間通訊, 
    父窗口往子窗口傳遞信息, 
    子窗口往父窗口傳遞信息。

8. 原生JS動態向一個div中插入1000個div標籤,如何實現?

此題主要考性能!

1)  能夠用JS中的createElement建立div,
    每當建立一個就把它添加到div中, 
    但會形成引起迴流的次數太多;

2)  使用字符串拼接的方式,
    把1000個div都拼接完成後,
    統一的添加到頁面中, 
    但會對div原有的元素標籤產生影響:
    原來標籤綁定的事件都消失了

3)  綜合1和2可使用文檔碎片方式來處理。

追問:若是是建立1000萬個呢?

可採用的方案: 數據分批異步加載
1)  首先把前兩屏幕的數據量
    (例如:300條)先獲取到,
    而後使用字符串拼接或者文檔碎片
    的方式綁定到頁面中; 

2)  當瀏覽器滾動到指定的區域的
    時候在加載300條...以此類推。

9. 程序出現bug了,你是如何調試的?

1)  在控制檯加斷點,    F10->逐過程  F11->逐語句;
2) 在代碼重點的位置加入console.log輸出對應的值來進行調試;
3) debugger調試;
4) 代碼分割還原調試;
5) 異常捕獲機制, 記錄運行日誌;
6) 單元測試。

10. 開發中是如何進行性能優化的?

如今框架(vue, react,...)、構建工具(webpack, ...)
已經給咱們解決掉大部分的性能優化問題, 
面試時, 能夠就你瞭解的框架來深刻剖析, 
但此題應該是考原生JS的範疇,
參考答案以下:
1) 雅虎35條性能優化黃金定律;
2) JS代碼優化:   a. 項目中的JS/CSS文件最好一個頁面只用一個,      須要把JS/CSS進行合併壓縮,      而且減小頁面中的垃圾冗餘代碼。      項目的資源文件在服務器上最好      作一下GZIP壓縮。    b. 解除文件緩存;     咱們修改代碼並上傳,     若是以前頁面訪問過該網站,     頗有可能不能當即見效;     咱們在引入CSS/JS文件的時候,     在文件名的後面加上版本號(加時間戳),     好比:    
    <script src='itlike.com.js?_=202001...'></script>;     當咱們上傳新的文件後     把時間戳改一下就能夠清除緩存了。  c. 移動端儘可能少用圖片:      icon能用svg畫的不用圖片;     靜態資源圖:作佈局的時候就能肯定下來的圖片,      好比:    
     1)css sprite圖片合併(針對於小圖片)
     2)作圖片延遲加載         (針對於大圖片 頭部的長條圖片、背景大圖...),         開始給一張默認的小的圖片         (最好維持在10kb之內)
     3)base64        (存在問題: 頁面的代碼太臃腫了,之後維護很差操做);          若是項目中因爲圖片太大實在解決不了,        改爲base64就解決了    d. 動態數據圖:     經過ajax從後臺讀取回來的圖片 , 圖片懶加載;  e. 音視頻文件的優化:     加載頁面的時候,儘可能不要加載音視頻文件,     當頁面中的其餘資源加載完成後,     再開始加載音視頻文件;     目前移動端常常給音視頻作的優化是:     走直播流文件(音頻後綴名是m3u8格式);  f. 減小頁面資源請求的次數:     若是當前只是一個宣傳頁,     或者是一個簡單的頁面,     使用的css和js能夠採用內嵌式開發;  g. ajax數據請求分批請求,     例如:一次要請求10000條數據的話,     咱們每一次只請求100條,第一屏幕確定能看全了,     當頁面滾動到對應的其它屏幕的時候,     在加載下一個100條...  h. 作數據的二次緩存,       能用CSS3作動畫的絕對不用JS,     能使用transform儘可能使用,     能用animation的進行不用transition...     儘可能減小同步操做,多用異步操做;     能使用原生JS本身編寫的,     絕對不用插件或者框架;  

 

 

11. 請描述下JS中事件冒泡機制?

冒泡型事件:事件按照從最特定的
事件目標到最不特定的事件目標
(document對象)的順序觸發。 捕獲型事件:事件從最不精確的對 象(document 對象)開始觸發,而後 到最精確。(也能夠在窗口級別捕獲 事件,不過必須由開發人員特別指定)。 支持W3C標準的瀏覽器在添加事件時 用addEventListener(event,fn,useCapture)方法, 基中第3個參數useCapture是一個Boolean值, 用來設置事件是在事件捕獲時執行, 仍是事件冒泡時執行。 而不兼容W3C的瀏覽器(IE)用attachEvent()方法, 此方法沒有相關設置, 不過IE的事件模型默認是在事件冒泡時執行的, 也就是在useCapture等於false的時候執行, 因此把在處理事件時把useCapture 設置爲false是比較安全, 也實現兼容瀏覽器的效果。

以下圖所示:前端

 

 

12. 爲何利用多個域名來提供網站資源會更有效?

1.CDN緩存更方便 2.突破瀏覽器併發限制 (通常每一個域名創建的連接不超過6個) 3.Cookieless,節省帶寬, 尤爲是上行帶寬通常比下行要慢; 4.對於UGC的內容和主站隔離, 防止沒必要要的安全問題 (上傳js竊取主站cookie之類的)。 正是這個緣由要求用戶內容的域名 必須不是本身主站的子域名, 而是一個徹底獨立的第三方域名。 5.數據作了劃分, 甚至切到了不一樣的物理集羣, 經過子域名來分流比較省事。 補充: 關於Cookie的問題, 帶寬是次要的,安全隔離纔是主要的。 關於多域名,也不是越多越好, 雖然服務器端能夠作泛解釋, 瀏覽器作dns解釋也是耗時間的, 並且太多域名,若是要走https的話, 還有要多買證書和部署的問題。

13. 請說出三種減小頁面加載時間的方法?

1.優化圖片;
精靈圖片, 字體圖標
SVG, GIF, WEBP
(可用在一些對顏色要求不高的地方)

2. 優化CSS
(壓縮合並css,
如margin-top,margin-left...)

3. 網址後加斜槓
(如www.itlike.com/目錄,
會判斷這個「目錄是什麼文件類型,
或者是目錄。)

4. 標籤標明高度和寬度
(若是瀏覽器沒有找到這兩個參數,
它須要一邊下載圖片一邊計算大小,
若是圖片不少,
瀏覽器須要不斷地調整頁面。
這不但影響速度,也影響瀏覽體驗。
當瀏覽器知道了高度和寬度參數後,
即便圖片暫時沒法顯示,
頁面上也會騰出圖片的空位,
而後繼續加載後面的內容。
從而加載時間快了,
瀏覽體驗也更好了。)

5.減小http請求
(合併文件,合併圖片)。

14. cookie 和session 的區別?

1. cookie數據存放在客戶的瀏覽器上, session數據放在服務器上。

2. cookie不是很安全, 別人能夠分析存放在本地的COOKIE, 並進行COOKIE欺騙, 考慮到安全應當使用session。

3. session會在必定時間內保存在服務器上。 當訪問增多,會比較佔用你服務器的性能 考慮到減輕服務器性能方面, 應當使用COOKIE。

4. 單個cookie保存的數據不能超過4K, 不少瀏覽器都限制一個站點最多保存20個cookie。

5. 開發建議:將登陸,用戶等重要信息存放爲session, 其餘信息若是須要保留,能夠放在cookie中。 PS: 額外閱讀 應用場景 常常登陸一個網站, 今天輸入用戶名密碼登陸了, 次日再打開不少狀況下就直接打開了 。這個時候用到的一個機制就是cookie。 session的一個場景是購物車, 添加了商品以後客戶端處 能夠知道添加了哪些商品, 而服務器端如何判別呢, 因此也須要存儲一些信息, 這裏就用到了session。 Cookie Cookie是訪問某些網站之後 在本地存儲的一些網站相關的信息, 下次再訪問的時候減小一些步驟。 另一個更準確的說法是: Cookies是服務器在本地機器上 存儲的小段文本並隨每個請求 發送至同一個服務器, 是一種在客戶端保持狀態的方案。 Cookie的主要內容包括: 名字,值,過時時間,路徑和域。 Session Session是存在服務器的 一種用來存放用戶數據的類 HashTable結構。 當瀏覽器 第一次發送請求時, 服務器自動生成了一個HashTable 和一個Session ID用來惟一標識這個HashTable, 並將其經過響應發送到瀏覽器。 當瀏覽器第二次發送請求, 會將前一次服務器響應中的Session ID 放在請求中一併發送到服務器上, 服務器從請求中提取出Session ID, 並和保存的全部Session ID進行對比, 找到這個用戶對應的HashTable。 通常這個值會有一個時間限制, 超時後毀掉這個值,默認是20分鐘。 Session的實現方式和Cookie有必定關係。 試想一下,創建一個鏈接就生成一個session id, 那麼打開幾個頁面就好幾個了, 這顯然不是咱們想要的, 那麼該怎麼區分呢? 這裏就用到了Cookie, 咱們能夠把session id存在Cookie中, 而後每次訪問的時候將 Session id帶過去就能夠識別了

15. 如何理解閉包?

爲何要使用閉包:
由於JS中變量的做用域分類:
全局變量和局部變量。

函數內部能夠讀取函數外部的全局變量;
在函數外部沒法讀取函數內的局部變量。

爲了讓函數執行完成後,內部的函數、變量還
能被調用,能夠採用閉包延長
局部變量/函數的生命週期。

定義和用法:
當一個函數的返回值是
另一個函數,而返回的那個函數
若是調用了其父函數內部的其它變量,
若是返回的這個函數在外部被執行,
就產生了閉包。

表現形式:
使函數外部可以調用
函數內部定義的變量。

使用場景:
排他、函數節流、網絡...

使用閉包的注意點:

濫用閉包,會形成內存泄漏;
因爲閉包會使得函數中的變量
都被保存在內存中,內存消耗很大,
因此不能濫用閉包,
不然會形成網頁的性能問題,
在IE中可能致使內存泄露。
解決方法是,在退出函數以前,
將不使用的局部變量指向null。

16.JS有哪些手段能夠實現繼承?

1. 原型鏈繼承
將父類的實例做爲子類的原型;

2. 藉助構造函數繼承
使用父類的構造函數來加強子類實例,
等因而複製父類的實例屬性給子類;
(沒用到原型)

3. 寄生組合繼承(完美)
經過寄生方式,
砍掉父類的實例屬性,
這樣,在調用兩次父類的構造的時候,
就不會初始化兩次實例方法/屬性,
避免的組合繼承的缺點

4. 組合繼承
經過調用父類構造,
繼承父類的屬性並保留傳參的優勢,
而後經過將父類實例做爲子類原型,
實現函數複用

5. 拷貝繼承
支持多繼承,沒法獲取父類
不可枚舉的方法

6. 實例繼承
爲父類實例添加新特性,
做爲子類實例返回

17. 用純JS實現,點擊一個列表時,輸出對應的索引?

方式一:
for(let i = 0,
   len = lis.length;
   i < len; i++){    lis[i].addEventListener('click',
     function () {        
       console.log(i);      }, false); } 方式二:
for(var i = 0,
   len = lis.length;
   i < len; i++) {    (function (i) {        lis[i].addEventListener        ('click', function () {            
            console.log(i);        }, false);    })(i) } 方式三:
let ul = document.querySelector('ul');
let lis = document.querySelectorAll('ul li'); ul.addEventListener('click', function (e) {    
 let target = e.target;    
 if(target.nodeName.toLowerCase() === 'li') {        
     console.log([].indexOf.call(lis, target));    } }, false);

18. 如下代碼有內存泄漏嗎?

var user = {    
   name: '撩課',    age: 12,    gender: '女'
};

var box = document.getElementById('box'); box.onclick = function() {    box.innerHTML = user.name; };
// ...其餘操做
user = null; // 釋放對象

答:存在內存泄漏, 這是js中垃圾回收的引用計數形成的。 徹底去除內存泄漏是不現實的,可是, 若是採用下面的方法能夠減小內存泄漏:

var user = {    
  name: '撩課',    
  age: 12,    
  gender: '女'
};

var box = document.getElementById('box'); (function (name) {    box.onclick = function() {        box.innerHTML = name;    }; })(user.name);
// ...其餘操做
user = null; // 釋放對象

 

19. es6中let,const,var的區別是什麼?

var :聲明全局變量;
let :聲明塊級變量,即局部變量, 定義後能夠修改;
const :用於聲明常量,就是定義後不能再修改值或者引用值的常量,也具備塊級做用域

20. 說說對es6中=>的理解?

箭頭函數至關於匿名函數,
而且簡化了函數定義,
箭頭左邊是參數,
右邊是返回值。

箭頭函數看上去
是匿名函數的一種簡寫,
但實際上,箭頭函數和
匿名函數有個明顯的區別:

箭頭函數內部的this是詞法做用域, 由上下文肯定。

21. 點擊按鈕發出ajax請求,如何防止用戶在此請求方式返回以前再次點擊?

// 點擊提交按鈕的時候,
// 把這個提交這個處理函數給解綁掉,
// 請求完成的時候在綁定回來
function clickHandler(){  $(this).unbind('click', clickHandler);    $.ajax({        
      url : 'url',        
      dataType : 'json',
       type : 'post',
       success : function (data) {
         if (data.success) {
          //提交成功作跳轉處理         } else {
          //處理失敗,從新綁定點擊事件          $(self).click(clickHandler);         }        }  }); }
                $('#itlike').click(clickHandler);
               
// 能夠點擊後讓按鈕不可用,
// 若是提交失敗能夠再次設置爲可用
// 1.讓按鈕不可用
$("#itlike").attr("disabled","disabled"); $.ajax({
   url : 'url',
   dataType : 'json',    
   type : 'post',    
   success : function (data) {
      if (data.success) {
      // 提交成功作跳轉處理       } else {            
      // 處理失敗,從新綁定點擊事件       // 2. 讓按鈕可用       $("#itlike").removeAttr("disabled");      }    } });

22. 請說明ECMAScript, JavaScript, Jscript之間的關係?

ECMAScript提供腳本語言必須遵照的規則、
細節和準則,是腳本語言的規範。
好比:ES5,ES6就是具體的一js版本。

JavaScript是ECMAScript的一個分支版本, 
JavaScript 實現了多數 ECMA-262 中
描述的 ECMAScript 規範,但存在少數差別。 

JScript是微軟公司對ECMA-262語言規範的
一種實現,除了少數例外(這是爲了保持向後兼容 ),
微軟公司宣稱JScript徹底實現了ECMA標準.

關係:
JavaScript和JScript都是ECMAScript的版本分支, 
兩者在語法上沒有多大的區別; 
只不過一個是NetScape公司的, 一個是微軟的;
IE系列默認是JScript, 其它的則反之用JavaScript。

23. 頁面加載過程當中可能觸發哪些事件? 它們的順序是?

頁面加載時,大體能夠分爲如下幾個步驟:
1)  開始解析HTML文檔結構;
2)  加載外部樣式表及JavaScript腳本;
3)  解析執行JavaScript腳本;
4)  DOM樹渲染完成;
5)  加載未完成的外部資源(如 圖片);
6)  頁面加載成功 執行順序:
1)  document readystatechange事件
2)  document DOMContentLoaded事件 3)  window load事件

24. 函數中在聲明變量a前使用a會產生錯誤嗎? 爲何?

不會, JS中可以進行變量做用域提高, 
把全部變量、函數的聲明提高到當前
做用域的最前面, 但不進行賦值操做;

因此可能形成獲取的值是undefined。

25. 什麼是hash, 以及hashchange事件?

先了解下什麼是hash:hash即URL中"#"字符後面的部分: a) 使用瀏覽器訪問網頁時, 若是網頁URL中帶有hash, 頁面就會定位到id(或name) 與hash值同樣的元素的位置;
b) hash還有另外一個特色, 它的改變不會致使頁面從新加載;
c) hash值瀏覽器是不會隨請求發送到服務器端的; d) 經過window.location.hash屬性獲取和設置hash值。 window.location.hash值的變化會直接 反應到瀏覽器地址欄(#後面的部分會發生變化),
同時,瀏覽器地址欄hash值的變化也會觸發 window.location.hash值的變化, 從而觸發onhashchange事件。 再來了解下什麼是hashchange事件: a) 當URL的片斷標識符更改時, 將觸發hashchange事件 (跟在#符號後面的URL部分,包括#符號)
b) hashchange事件觸發時, 事件對象會有hash改變前的URL (oldURL)和hash改變後的URL (newURL)兩個屬性。

26. 什麼是CDN, CDN對於網站有什麼意義, 它有什麼樣的缺點?

CDN又稱爲內容分發網絡;  本意在於
儘量避開互聯網上有可能影響數據
傳輸速度和穩定性的瓶頸和環節,
使內容傳輸的更快、更穩定。

主要目的:

解決因分佈、帶寬、服務器性能帶來的訪問延遲問題,
適用於站點加速、點播、直播等場景。

使用戶可就近取得所需內容,
解決 Internet網絡擁擠的情況,
提升用戶訪問網站的響應速度和成功率。 缺點: a) 實施複雜 , 投資大; b) 目前大部分的CDN還只是對靜態內容加速, 對動態加速效果很差; 而雙線對動態加速的效果跟靜態是同樣的。

27. 說說你對做用域鏈的理解?

做用域鏈的做用是保證執行環境裏
有權訪問的變量和函數是有序的,
做用域鏈的變量只能向上訪問,
變量訪問到window對象即被終止, 做用域鏈向下訪問變量是不被容許的; 做用域就是變量與函數的可訪問範圍, 即做用域控制着變量與函數的可見性 和生命週期。

28. 請說說JavaScript原型,原型鏈 ?

原型: 
當咱們訪問一個對象的屬性時, 
每一個對象都會在其內部初始化一個屬性,
就是prototype(原型);

原型鏈:
若是這個對象內部不存在這個屬性,
那麼他就會去prototype裏找這個屬性,
這個prototype又會有本身的prototype,
因而就這樣一直找下去,
也就是咱們平時所說的原型鏈;

二者關係:
instance.constructor.prototype = instance.__proto__

29. 請解釋什麼是事件代理?

事件代理(Event Delegation),
又稱之爲事件委託。
是 JavaScript 中經常使用綁定事件
的經常使用技巧。

「事件代理」便是把本來須要綁定
的事件委託給父元素,讓父元素
擔當事件監聽的角色。

事件代理的原理是DOM元素的事件冒泡。
使用事件代理的好處是能夠提升性能, 
能夠大量節省內存佔用,減小事件註冊,
好比在ul上代理全部li的click事件;

此外, 還能夠實現動態新增子對象時無需
再次對其綁定事件。

30. new操做符具體完成了哪幾個操做?

1) 建立一個空對象, 定義this 變量引用該對象,同時還繼承了該函數的原型;
2) 屬性和方法被加入到 this 引用的對象中;
3) 新建立的對象由 this 所引用, 而且最後隱式的返回 this

31. 說幾條寫JavaScript的基本規範?

1) 不要在同一行聲明多個變量;
2) 請使用===/!==來比較true/false或者數值;
3) 使用對象字面量替代new Object這種形式;
4) 減小使用全局函數, 全局變量;
5) switch語句必須帶有default分支;
6) if語句必須使用大括號;
7) for-in循環中的變量; 應該使用var關鍵字明確限定做用域; 從而避免做用域全局污染。

32. 如何解決跨域問題?

1) jsonp
2) iframe
3) window.name 4) window.postMessage 5) 服務器上設置代理頁面

33. XML和JSON的區別?

1) 數據體積方面JSON相對於XML來說, 數據的體積小,傳遞的速度更快些。
2) 數據交互方面JSON與JavaScript的交互更加方便, 更容易解析處理,更好的數據交互。
3) 數據描述方面;JSON對數據的描述性比XML較差。
4) 傳輸速度方面:JSON的速度要遠遠快於XML。

34. 在Javascript中什麼是僞數組?如何將僞數組轉化爲標準數組?

僞數組(類數組):
沒法直接調用數組方法, 
length屬性有什麼特殊的行爲, 但仍能夠對真正數組遍歷方法來遍歷它們。 典型的是函數的argument參數,
還有像調getElementsByTagName,document.childNodes之類的, 它們都返回NodeList對象,  這些都屬於僞數組。 可使用Array.prototype.slice.call(fArray)將數組 轉化爲真正的Array對象。

35. 一次完整的HTTP事務是怎樣的一個過程?

基本流程:
a. 域名解析;
b. 發起TCP的3次握手;
c. 創建TCP鏈接後發起http請求;
d. 服務器端響應http請求,瀏覽器獲得html代碼;
e. 瀏覽器解析html代碼,並請求html代碼中的資源;
f. 瀏覽器對頁面進行渲染呈現給用戶

36. 開發中有哪些常見的Web攻擊技術?

a) XSS
(Cross-Site Scripting,跨站腳本攻擊) 指經過存在安全漏洞的Web網站註冊用戶的瀏覽器 內運行非法的HTML標籤或者JavaScript進行的一種攻擊。 b)SQL注入 c) CSRF
(Cross-Site Request Forgeries,跨站點請求僞造) 指攻擊者經過設置好的陷阱,強制對已完成的認證用戶進行 非預期的我的信息或設定信息等某些狀態更新。

---華麗分割線---vue

 

3、H5+C3部分html5

 

1. 垂直水平居中的方式?

/** 方式一:  定位 父元素設置爲:position: relative; 子元素設置爲:position: absolute; 距上50%,據左50%,而後減去元素自身寬度的距離就能夠實現 */

width: 100px; height: 100px; position: absolute; left: 50%; top: 50%; margin: -50px 0 0 -50px;

/** 方式二:  flex佈局 */
display: flex;  //flex佈局
justify-content: center; // 使子項目水平居中
align-items: center; // 使子項目垂直居中

/** 方式三:  table-cell  (不推薦) */
display: table-cell; vertical-align: middle;//使子元素垂直居中
text-align: center;//使子元素水平居中

2. 實現一個三欄佈局,中間版塊自適應方法有哪些?

// 方式一: 浮動和定位
<div class="content">   <div class="left">left</div>   <div class="right">right</div>   <div class="center">center</div> </div> .left{    float: left;    width: 100px;    height: 200px; } .right{    float: right;    padding: 0;    width: 100px;    height: 200px; } .center{    margin: 0 100px 0 200px; } 方式二:  將父容器的position設置爲relative,兩個邊欄的position設置成absolute。

 

3. margin坍塌?

當兩個盒子在垂直方向上設置margin值時,會出現塌陷現象。 解決方案主要包括: 1. 給父盒子添加border; 2. 給父盒子添加padding-top; 3. 給父盒子添加overflow:hidden; 4. 父盒子position:fixed; 5. 父盒子display:table; 6. 給子元素的前面添加一個兄弟元素 屬性爲content:"";overflow:hidden;

4. 說說BFC原理?

BFC就是頁面上的一個隔離的獨立容器,
容器裏面的子元素不會影響到外面的元素。

由於BFC內部的元素和外部的元素絕對不會互相影響,
所以,當BFC外部存在浮動時,
它不會影響BFC內部Box的佈局,
BFC會經過變窄,而不與浮動有重疊。

一樣的,當BFC內部有浮動時,
爲了避免影響外部元素的佈局,
BFC計算高度時會包括浮動的高度。
避免margin重疊也是這樣的一個道理。

5. 爲何要清除浮動?舉個實際場景?

父元素的高度是由子元素撐開的,
且子元素設置了浮動,
父元素沒有設置浮動,
子元素脫離了標準的文檔流,
那麼父元素的高度會將其忽略,
若是不清除浮動,
父元素會出現高度不夠,
那樣若是設置border或者background都得不到正確的解析。 方式:
.clearfix::after,
.clearfix::before{  
  content:"";  
  display:table;  
  clear:both; }

6. 你能描述一下漸進加強和優雅降級之間的不一樣嗎?

定義:
優雅降級(graceful degradation):
一開始就構建站點的完整功能,
而後針對瀏覽器測試和修復

漸進加強(progressive enhancement): 
一開始只構建站點的最少特性,
而後不斷針對各瀏覽器追加功能。

優雅降級和漸進加強都關注於同一網站
在不一樣設備裏不一樣瀏覽器下的表現程度。

區別:
「優雅降級」觀點認爲應該針對那些最高級、
最完善的瀏覽器來設計網站。

而將那些被認爲「過期」或有功能缺失的瀏覽器下
的測試工做安排在開發週期的最後階段,並把測試
對象限定爲主流瀏覽器(如 IE、Mozilla 等)的
前一個版本。

「漸進加強」觀點則認爲應關注於內容自己。

總結:
"優雅降級"就是首先完整地實現整個網站, 包括其中的功能和效果. 而後再爲那些無 法支持全部功能的瀏覽器增長候選方案, 使之在舊式瀏覽器上以某種形式降級體驗 卻不至於徹底失效。

"漸進加強"則是從瀏覽器支持的基本功能開始, 首先爲全部設備準備好清晰且語義化的html及 完整內容, 而後再以無侵入的方法向頁面增長無 害於基礎瀏覽器的額外樣式和功能。 當瀏覽器升級時, 它們會自動呈現併發揮做用。

7. 請說說瀏覽器內核的組成?

瀏覽器的結構:

1)用戶界面(UI)
包括菜單欄、工具欄、地址欄、後退/前進按鈕、書籤目錄等,
也就是能看到的除了顯示頁面的主窗口以外的部分; 2)瀏覽器引擎(Rendering engine)
也被稱爲瀏覽器內核、渲染引擎,主要負責取得頁面內容、
整理信息(應用CSS)、計算頁面的顯示方式,而後會輸出到 顯示器或者打印機; 3)JS解釋器
也能夠稱爲JS內核,主要負責處理javascript腳本程序,
通常都會附帶在瀏覽器之中,例如chrome的V8引擎; 4)網絡部分
主要用於網絡調用,例如:HTTP請求,
其接口與平臺無關,併爲全部的平臺提供底層實現; 5)UI後端
用於繪製基本的窗口部件,好比組合框和窗口等。 6)數據存儲
保存相似於cookie、storage等數據部分, HTML5新增了web database技術,一種完整的輕量級客 戶端存儲技術。 主要瀏覽器: IE、Firefox、Safari、Chrome、Opera。 它們的瀏覽器內核(渲染引擎): IE--Trident FF(Mozilla)--Gecko Safari--Webkit Chrome--Blink(WebKit的分支) Opera--原爲Presto,現爲Blink

8. 爲何利用多個域名來請求網絡資源會更有效?

動靜分離需求,使用不一樣的服務器處理請求。
處理動態內容的只處理動態內容,不處理別的,
提升效率。

突破瀏覽器併發限制, 同一時間針對同一域名
下的請求有必定數量限制。超過限制數目的請
求會被阻止。不一樣瀏覽器這個限制的數目不同。

Cookieless, 節省帶寬,尤爲是上行帶寬通常比下
行要慢。用戶的每次訪問,都會帶上本身的cookie
,長此以往耗費的帶寬仍是挺大的。

假如weibo 的圖片放在主站域名下,那麼用戶
每次訪問圖片時,request header 裏就會帶有
本身的cookie ,header 裏的cookie 還不能壓縮,
而圖片是不須要知道用戶的cookie 的,因此這部分帶
寬就白白浪費了。

避免沒必要要的安全問題(好比: 上傳js竊取主站cookie之類的)

節約主域名的鏈接數,從而提升客戶端網絡帶寬的利用率,
優化頁面響應。

9. 說說前端開發中, 如何進行性能優化?

1) 減小http請求次數:css spirit,data uri;
2) JS,CSS源碼壓縮;
3) 前端模板 JS+數據,減小因爲HTML標籤致使
    的帶寬浪費,前端用變量保存AJAX請求結果,每
    次操做本地變量,不用請求,減小請求次數;
4) 用innerHTML代替DOM操做,減小DOM操做次數;
5) 用setTimeout來避免頁面失去響應;
6) 用hash-table來優化查找; 7) 當須要設置的樣式不少時設置className而不    是直接操做style; 8) 少用全局變量; 9) 緩存DOM節點查找的結果; 10) 避免使用CSS Expression; 11) 圖片預載; 12) 避免在頁面的主體佈局中使用table, table要等其中的內容徹底下載以後纔會顯示出來, 顯示比div+css佈局慢; 13) 控制網頁在網絡傳輸過程當中的數據量; 好比: 啓用GZIP壓縮或者保持良好的編程習慣, 避免重複的CSS,JavaScript代碼, 多餘的HTML標籤和屬性。    

10. 從前端角度出發, 談談作好網站seo須要考慮什麼?

1) 語義化html標籤;
2) 合理的title, description, keywords;
3) 重要的html代碼放前面;
4) 少用iframe, 搜索引擎不會抓取iframe中的內容
5) 圖片加上alt

11. HTTP狀態碼及其含義?

1XX:信息狀態碼
100 Continue 繼續,通常在發送post請求時, 已發送了http header以後服務端將返回此信息, 表示確認,以後發送具體參數信息;

2XX:成功狀態碼
200 OK 正常返回信息
201 Created 請求成功而且服務器建立了新的資源
202 Accepted 服務器已接受請求,但還沒有處理

3XX:重定向
301 Moved Permanently 請求的網頁已永久移動到新位置。
302 Found 臨時性重定向。
303 See Other 臨時性重定向,且老是使用 GET 請求新的 URI。
304 Not Modified 自從上次請求後,請求的網頁未修改過。

4XX:客戶端錯誤
400 Bad Request 服務器沒法理解請求的格式, 客戶端不該當嘗試再次使用相同的內容發起請求。
401 Unauthorized 請求未受權。
403 Forbidden 禁止訪問。
404 Not Found 找不到如何與 URI 相匹配的資源。

5XX: 服務器錯誤
500 Internal Server Error 最多見的服務器端錯誤。
503 Service Unavailable 服務器端暫時沒法處理請求 (多是過載或維護)。

12. html5有哪些新特性、移除了那些元素?

HTML5 如今已經不是 SGML 的子集,
主要是關於圖像,位置,存儲,多任務等功能的增長: 1) 繪畫標籤canvas; 2) 用於媒介回放的 video 和 audio 元素; 3) 本地離線存儲 localStorage 長期存儲數據, 瀏覽器關閉後數據不丟失; 4) sessionStorage的數據在瀏覽器關閉後自動刪除; 5) 語意化更好的內容元素, 好比article、footer、header、nav、section; 6) 表單控件,calendar、date、time、email、url、search; 7) webworker, websocket, Geolocation; 移除的元素: 1) 純表現的元素:basefont,big,center,font, s,strike,tt,... 2) 對可用性產生負面影響的元素:frame,frameset,noframes

13. display: none;與visibility: hidden;的區別?

相同點:它們都能讓元素不可見

不一樣點:
display:none;會讓元素徹底從渲染樹中消失, 渲染的時候不佔據任何空間;

visibility: hidden;不會讓元素從渲染樹消失, 渲染師元素繼續佔據空間,只是內容不可見;

display: none;是非繼承屬性, 子孫節點消失因爲元素從渲染樹消失形成, 經過修改子孫節點屬性沒法顯示;

visibility: hidden;是繼承屬性, 子孫節點消失因爲繼承了hidden, 經過設置visibility: visible;可讓子孫節點顯示; 修改常規流中元素的display一般會形成文檔重排。 修改visibility屬性只會形成本元素的重繪。 讀屏器不會讀取display: none;元素內容; 會讀取visibility: hidden;元素內容

14. px和em的區別?

px和em都是長度單位;

區別是: 
px的值是固定的,指定是多少就是多少,
計算比較容易。

em得值不是固定的,而且em會繼承父級元素的字體大小。

瀏覽器的默認字體高都是16px;
因此未經調整的瀏覽器都符合: 1em=16px;
那麼12px=0.75em, 10px=0.625em

15. CSS 去掉inline-block元素間隙的幾種方法?

間隙是怎麼來的:

間隙是由換行或者回車致使的;
只要把標籤寫成一行或者
標籤直接沒有空格,就不會出現間隙;

怎麼去除?

方法1:
元素間的間隙出現的緣由
是元素標籤之間的空格,
把空格去掉間隙天然就會消失。
<div class="itlike">  <span>撩課itlike</span><span>撩課itlike</span>
</div>

方法2: 利用HTML註釋標籤
<div class="demo">    <span>撩課itlike</span>
   <!-- -->
   <span>撩課itlike</span>
</div>

方法3: 取消標籤閉合
<div class="demo">    <span>撩課itlike
   <span>撩課itlike
   <span>撩課itlike
   <span>撩課itlike
</div>

方法4: 在父容器上使用font-size:0;能夠消除間隙
<div class="demo">    <span>撩課itlike</span>    <span>撩課itlike</span>    <span>撩課itlike</span>    <span>撩課itlike</span>
</div>.demo {font-size: 0;}
相關文章
相關標籤/搜索