JavaScript 面試題(未完待續)

1. ECMAScrit 中數組的大小

   如題:javascript

var array = new Array();
    array[0] = 0;
    array[1] = 1;
    array[2] = 2;
    array[5] = 5;
    console.log(array.length); // 6
解析:
    
    ECMAScript 中數組的大小是能夠動態調整的,既能夠隨着數據的添加自動增加以容納新增的數據。
    當把一個值放在超出當前數組大小的位置上時,數組就會從新計算長度值,
    即長度值等於最後一項的索引加一,前面的值都將被自動賦值爲 undefined。

2. RegExp 對象的方法

   如題:下面選項中不是 RegExp 對象的方法的是 : html

   A. test B. match C. exec D. compile java

  正確答案選擇 B.git

解析:

    JavaScript RegExp 對象有 3 個方法:test()、 exec()、compile()。
    
    1. test() 方法用於檢測一個字符串是否匹配某個正則表達式,若是匹配,返回 true ,不然返回 false;
    2. exec() 方法用來檢測字符串中的正則表達式匹配的值,exec() 方法返回一個數組,其中存放匹配的結果。
    若是未找到匹配的值,則返回 null;
    3.compile() 方法能夠在腳本執行過程當中編譯正則表達式,也能夠改變已有的表達式。

3. 下面哪些方法能夠用於 JavaScript 的異步編程

   A. 回調函數 B. 事件監聽 C. 監聽/訂閱 D. Promise 對象github

  正確答案選擇 A,B,C,D.正則表達式

解析:

  回調函數是異步編程的基礎。
  
  事件監聽,另外一種思路是採用事件驅動模式。任務的執行不取決於代碼的順序,而是取決於事件是否發生。
  
  監聽/訂閱,上一節的「事件」能夠理解爲「型號」。
  
  Promise 對象,是 CommonJS 工做組提出的一種規範,目的是爲異步編程提供統一接口

4. w3c 爲 JavaScript 定製的標準事件模型,如下正確的順序和描述是

  • A. 事件捕獲 -> 事件冒泡
  • B. 事件捕獲 -> 事件處理 -> 事件冒泡
  • C. 事件冒泡 -> 事件處理
  • D. 事件冒泡 -> 事件處理 -> 事件捕獲
  • E. 事件處理 -> 事件捕獲 -> 事件冒泡

  正確答案選擇 B.數據庫

解析:
    
    先事件捕獲從 windows > document 往下級直到特定的事件節點,而後進行事件處理,再事件冒泡,
    從特定節點往上級,這個完整的過程。

5. 下面關於 DNS 說法正取的是

  • A. DNS 的做用是域名與 IP 地址的相互映射
  • B. DNS 協議 運行在 UDP 協議之上
  • C. DNS 協議的端口號是 53
  • D. DNS 默認緩存時間爲 1 小時

  正確答案選擇 B,C.apache

解析:
    
    DNS(Domain Name System,域名系統),因特網上做爲域名與 IP 地址的相互映射的一個分佈式數據庫,可以使用戶更方便的使用互聯網,
    而不用去記住可以被機器直接讀取的 IP 數串。
    經過主機名,最終獲得該主機名對應的 IP 地址的過程叫作域名解析(或主機名解析)。
    DNS 協議運行在 UDP 協議之上,使用端口號爲 52。

6. 編寫獲取 Url 參數值的代碼,以鍵值對返回。

  例:
url = "https://cn.bing.com/search?q=LeetCode&qs=n"編程

  返回結果 { q: "LeetCode", qs: "n" }windows

  實現代碼:

  • 使用截取字符串的方式實現
/**
     * 經過截取字符串獲取 url 參數
     * @param {*} requestUrl 
     */
    function queryURLParameter(requestUrl) {
        const obj = {};
        let index = 0;
        // 判斷 url 地址是否有參數
        if ((index = requestUrl.indexOf('?')) > 0) {
            // 截取 ? 後的字符串
            requestUrl = requestUrl.substr(index + 1);
            // 切分 & 符號後的參數
            requestUrl.split('&').forEach(item => {
                const param = item.split('=');
                obj[param[0]] = param[1];
            });
        }
        return obj;
    }
  • 使用正則表達式的方式實現
/**
     * 經過正則表達式來獲取 url 參數
     * @param {*} requestUrl 
     */
    function queryURLParameter(requestUrl) {
        // 編寫獲取 url 參數的正則表達式
        let reg = /([^?&=]+)=([^?&=]+)/g;
        const obj = {};
        // 經過配置正則獲取數值
        requestUrl.replace(reg, (...arg)=>{
            obj[arg[1]] = arg[2];
        });
        return obj;
    }

7. 如下代碼的輸出結果。

var a = 4;
    function b(x, y, a){
        console.log(a);
        arguments[2] = 10;
        console.log(a);
    }
    a = b(1, 2, 3);
    console.log(a);
  • A. 3 3 4
  • B. 3 10 4
  • C. 3 10 10
  • D. 3 10 undefined

  正確答案選擇 D.

解析:
    
    在 JavaScript 的非嚴格模式下,函數的實參集合與形參變量存在「映射」關係:不管其中誰發生改變,另外一個也會跟着改變;
    
    在 JavaScript 的嚴格模式下,arguments 和形參變量的映射關係被切斷,互相之間互不干擾。

8. 請分別說出下列代碼中 a、b、c 輸出的值

function fun(n, o) {
        console.log(o);
        return function (m) {
            return fun(m, n);
        };
    };
    
    const a = fun(0);
    a(1);
    a(2);
    a(3);
    
    const b = fun(0)(1)(2)(3);
    
    const c = fun(0)(1);
    c(2);
    c(3);

  正確答案:

a 輸出結果: undefined,0,0,0
    
    b 輸出結果: undefined,0,1,2
    
    c 輸出結果: undefined,0,1,1
解析:
    a 的運行中,第一次 fun(0) 所調用的是第一層函數,因爲參數 o 並未傳值,此時 o = undefined;
    a(1) 是在調用前一個 fun(0) 的返回值也就是 function(m){ return fun(m,n) };並內部調用 fun(m,n),此時內部 fun(m,n) 中的 n 閉包了外層 fun(n,o) 中的 n,因爲第一次調用 n = 0;即 m = 1,n = 0;
    同理 a(2) 中調用的是前一個 a(1) 的返回值,即 fun(m,n),因此仍是閉包了第一次 n 的值,即 m = 2, n = 0;
    以此類推
    
    b 的運行中,第一次 fun(0) 所調用的是第一層函數,因爲參數 o 並未傳值,此時 o = undefined;
    b(1) 是在調用前一個 fun(0) 的返回值也就是 function(m){ return fun(m,n) };並內部調用 fun(m,n),此時內部 fun(m,n) 中的 n 閉包了外層 fun(n,o) 中的 n,因爲第一次調用 n = 0;即 m = 1,n = 0;
    b(1)(2) 此時調用的並非上一層返回的值,而是直接調用的上一層返回值的內部函數,即 fun(m,n);因爲 fun(m,n) 中的 n 閉包了外層 fun(n,o) 中的 n,即 b(1),所以 n = 1;
    以此類推
    
    c 的運行中,c(0)(1) 與 b(1)(2) 的推斷類似,只不過此時的 fun(m,n) 中的 n 閉包了外層 fun(n,o) 中的 n,即 c(0),所以 n = 0;
    c(2) 與 a(1) 的推斷類似,只不過 只不過此時的 fun(m,n) 中的 n 閉包了外層 fun(n,o) 中的 n,即 c(1),所以 n = 1;
    以此類推

9. 如下哪一項不屬於瀏覽器 Response Headers 字段

  • A. Referer
  • B. Connection
  • C. Content-Type
  • D. Server

  正確答案選擇 A.

解析:
    
    常見的請求頭部和響應頭部
    
    請求(客戶端 -> 服務端[request])
    
        GET(請求的方式) /newcoder/hello.html(請求的目標資源) HTTP/1.1(請求採用的協議和版本號) 
        Accept: */*(客戶端能接收的資源類型) 
        Accept-Language: en-us(客戶端接收的語言類型) 
        Connection: Keep-Alive(維護客戶端和服務端的鏈接關係)
        Host: localhost:8080(鏈接的目標主機和端口號)
        Referer: http://localhost/links.asp(告訴服務器我來自於哪裏)
        User-Agent: Mozilla/4.0(客戶端版本號的名字)
        Accept-Encoding: gzip, deflate(客戶端能接收的壓縮數據的類型) 
        If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT(緩存時間)  
        Cookie(客戶端暫存服務端的信息) 
        Date: Tue, 11 Jul 2000 18:23:51 GMT(客戶端請求服務端的時間)
        
    響應(服務端->客戶端[response])
    
        HTTP/1.1(響應採用的協議和版本號) 200(狀態碼) OK(描述信息)
        Location: http://www.baidu.com(服務端須要客戶端訪問的頁面路徑)
        Server:apache tomcat(服務端的Web服務端名)
        Content-Encoding: gzip(服務端可以發送壓縮編碼類型) Content-Length: 80(服務端發送的壓縮數據的長度) 
        Content-Language: zh-cn(服務端發送的語言類型) 
        Content-Type: text/html; charset=GB2312(服務端發送的類型及採用的編碼方式)
        Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT(服務端對該資源最後修改的時間)
        Refresh: 1;url=http://www.it315.org(服務端要求客戶端1秒鐘後,刷新,而後訪問指定的頁面路徑)
        Content-Disposition: attachment; filename=aaa.zip(服務端要求客戶端如下載文件的方式打開該文件)
        Transfer-Encoding: chunked(分塊傳遞數據到客戶端)
        Set-Cookie:SS=Q0=5Lb_nQ; path=/search(服務端發送到客戶端的暫存數據)
        Expires: -1//3種(服務端禁止客戶端緩存頁面數據)
        Cache-Control: no-cache(服務端禁止客戶端緩存頁面數據)  
        Pragma: no-cache(服務端禁止客戶端緩存頁面數據) 
        Connection: close(1.0)/(1.1)Keep-Alive(維護客戶端和服務端的鏈接關係)  
        Date: Tue, 11 Jul 2000 18:23:51 GMT(服務端響應客戶端的時間)
        
    在服務器響應客戶端的時候,帶上Access-Control-Allow-Origin頭信息,解決跨域的一種方法。

10. 對任意給定的 32 位整數,轉換二進制並統計 1 出現的個數

  實現代碼:

num.toString(2).match(new RegExp('1','g')).length;

11. 根據包名,在指定空間中建立對象

例:

輸入:namespace({a: {test: 1, b: 2}}, 'a.b.c.d')
    
    輸出:{a: {test: 1, b: {c: {d: {}}}}}

  實現代碼:

function namespace(oNamespace, sPackage) {
        var keys = sPackage.split('.');
        var tempSpace = oNamespace;
        keys.forEach(function(key){
            if(!(tempSpace[key] instanceof Object)){
                tempSpace[key] = {};
            }
            tempSpace = tempSpace[key];
        });
        return oNamespace;
    }

12. 爲 Array 對象添加一個去除重複項的方法

例:

輸入:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]
    
    輸出:[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']
解析:
    
    在 indexOf 判斷中,NaN 和空對象 {} 均返回 -1,所以要判斷 NaN 實現對其去重。
    
    因爲空對象 {} 所指向的內存地址不一致,所以能夠不對其考慮。
    
    在 JavaScript 中存在 6 個假值:flase, 0, null, "", undefined, NaN。
    
    前 5 個的判斷可直接使用嚴格相等 「===」 判斷,而 NaN 特殊性在於不等於其自身。

  ES5 實現代碼:

Array.prototype.uniq = function(){
        return this.filter(function(item,index){
            return item != item ? this.flag = this.flag === undefined : this.indexOf(item) === index;
        },this);
    }

  ES6 實現代碼:

Array.prototype.uniq = function(){
        [...new Set(this)]
    }

  文章原文地址 https://github.com/SilenceHVK/blog/issues/18,歡迎 Star、Watch

相關文章
相關標籤/搜索