前端面試題 | JS部分(附帶答案)


目前在找工作,所以各方收集了一堆面試題。其實刷面試題的過程也能更新自己對知識的認識,所以也提醒自己多看多理解。如果對下面題目有更深理解,會實時更新。遇到新題目,也會不定時更新。希望能幫助到部分朋友~

 

一、各種函數方法定義及區別

1. typeof運算符和instanceof運算符以及isPrototypeOf()方法的區別

typeof是一個運算符,用於檢測數據的類型,比如基本數據類型null、undefined、string、number、boolean,以及引用數據類型object、function,但是對於正則表達式、日期、數組這些引用數據類型,它會全部識別為object; instanceof同樣也是一個運算符,它就能很好識別數據具體是哪一種引用類型。它與isPrototypeOf的區別就是它是用來檢測構造函數的原型是否存在於指定對象的原型鏈當中;而isPrototypeOf是用來檢測調用此方法的對象是否存在於指定對象的原型鏈中,所以本質上就是檢測目標不同。

2.call()和apply()的區別

實際上,apply和call的功能是一樣的,只是傳入的參數列表形式不同。apply:最多只能有兩個參數——新this對象和一個數組argArray。

參考:www.cnblogs.com/lengyuehuah…

3.全局函數eval()有什么作用?

eval()只有一個參數,如果傳入的參數不是字符串,它直接返回這個參數。如果參數是字符串,它會把字符串當成javascript代碼進行編譯。如果編譯失敗則拋出一個語法錯誤(syntaxError)異常。如果編譯成功,則開始執行這段代碼,並返回字符串中的最后一個表達式或語句的值,如果最后一個表達式或語句沒有值,則最終返回undefined。如果字符串拋出一個異常,這個異常將把該調用傳遞給eval()。

4.描述以下變量的區別:null,undefined或undeclared

null 表示"沒有對象",即該處不應該有值,轉為數值時為0。典型用法是:

(1) 作為函數的參數,表示該函數的參數不是對象。

(2) 作為對象原型鏈的終點。

undefined 表示"缺少值",就是此處應該有一個值,但是還沒有定義,轉為數值時為NaN。典型用法是:

(1)變量被聲明了,但沒有賦值時,就等於undefined。

(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。

(3)對象沒有賦值的屬性,該屬性的值為undefined。

(4)函數沒有返回值時,默認返回undefined。

undeclared :js語法錯誤,沒有申明直接使用,js無法找到對應的上下文。

5.==和===有什么區別?

首先,== equality 等同,=== identity 恆等。==,兩邊值類型不同的時候,要先進行類型轉換,再比較。===,不做類型轉換,類型不同的一定不等。

先說 ===,這個比較簡單。下面的規則用來判斷兩個值是否===相等:

如果類型不同,就[不相等] 
如果兩個都是數值,並且是同一個值,那么[相等];(!例外)的是,如果其中至少一個是NaN,那么[不相等]。(判斷一個值是否是NaN,只能用isNaN()來判斷) 
如果兩個都是字符串,每個位置的字符都一樣,那么[相等];否則[不相等]。 
如果兩個值都是true,或者都是false,那么[相等]。 
如果兩個值都引用同一個對象或函數,那么[相等];否則[不相等]。 
如果兩個值都是null,或者都是undefined,那么[相等]。 

 

 

再說 ==,根據以下規則: 如果兩個值類型相同,進行 === 比較。 如果兩個值類型不同,他們可能相等。根據下面規則進行類型轉換再比較:

如果一個是null、一個是undefined,那么[相等]。 
如果一個是字符串,一個是數值,把字符串轉換成數值再進行比較。 
如果任一值是 true,把它轉換成 1 再比較;如果任一值是 false,把它轉換成 0 再比較。 
如果一個是對象,另一個是數值或字符串,把對象轉換成基礎類型的值再比較。對象轉換成基礎類型,利用它的
toString或者valueOf方法。js核心內置類,會嘗試valueOf先於toString;例外的是Date,Date利用的是toString轉換。非js核心的對象,令說(比較麻煩,我也不大懂) 
任何其他組合,都[不相等]。

 



6.同步異步?

1、進程同步:就是在發出一個功能調用時,在沒有得到結果之前,該調用就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事 2、異步的概念和同步相對。當一個異步過程調用發出后,調用者不能立刻得到結果。實際處理這個調用的部件在完成后,通過狀態、通知和回調來通知調用者。

 

 

二、各種概念/原理

1. 什么是事件代理/事件委托?

事件代理/事件委托是利用事件冒泡的特性,將本應該綁定在多個元素上的事件綁定在他們的祖先元素上,尤其在動態添加子元素的時候,可以非常方便的提高程序性能,減小內存空間。

2.什么是事件冒泡?什么是事件捕獲?

冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發。

捕獲型事件:事件從最不精確的對象(document 對象)開始觸發,然后到最精確(也可以在窗口級別捕獲事件,不過必須由開發人員特別指定)。

支持W3C標准的瀏覽器在添加事件時用addEventListener(event,fn,useCapture)方法,基中第3個參數useCapture是一個Boolean值,用來設置事件是在事件捕獲時執行,還是事件冒泡時執行。而不兼容W3C的瀏覽器(IE)用attachEvent()方法,此方法沒有相關設置,不過IE的事件模型默認是在事件冒泡時執行的,也就是在useCapture等於false的時候執行,所以把在處理事件時把useCapture設置為false是比較安全,也實現兼容瀏覽器的效果。

3.如何阻止冒泡?

w3c的方法是e.stopPropagation(),IE則是使用e.cancelBubble = true。例如: window.event? window.event.cancelBubble = true : e.stopPropagation();

return false也可以阻止冒泡。

4.如何阻止默認事件?

w3c的方法是e.preventDefault(),IE則是使用e.returnValue = false,比如:

function stopDefault( e ) { 
    //阻止默認瀏覽器動作(W3C) 
    if ( e && e.preventDefault ) 
        e.preventDefault(); 
    //IE中阻止函數器默認動作的方式 
    else 
        window.event.returnValue = false; 
}

 

return false也能阻止默認行為。

5.簡述javascript中this的指向

第一准則是:this永遠指向函數運行時所在的對象,而不是函數被創建時所在的對象。

  • 普通的函數調用,函數被誰調用,this就是誰。
  • 構造函數的話,如果不用new操作符而直接調用,那即this指向window。用new操作符生成對象實例后,this就指向了新生成的對象。
  • 匿名函數或不處於任何對象中的函數指向window 。
  • 如果是call,apply等,指定的this是誰,就是誰。
  • 參考:www.cnblogs.com/beidan/p/53…

5.原生對象和宿主對象

原生對象是ECMAScript規定的對象,所有內置對象都是原生對象,比如Array、Date、RegExp等;

宿主對象是宿主環境比如瀏覽器規定的對象,用於完善是ECMAScript的執行環境,比如Document、Location、Navigator等。

6.基本數據類型和引用數據類型

基本數據類型指的是簡單的數據段,有5種,包括null、undefined、string、boolean、number;

引用數據類型指的是有多個值構成的對象,包括object、array、date、regexp、function等。

主要區別:

  • 聲明變量時不同的內存分配:前者由於占據的空間大小固定且較小,會被存儲在棧當中,也就是變量訪問的位置;后者則存儲在堆當中,變量訪問的其實是一個指針,它指向存儲對象的內存地址。
  • 也正是因為內存分配不同,在復制變量時也不一樣。前者復制后2個變量是獨立的,因為是把值拷貝了一份;后者則是復制了一個指針,2個變量指向的值是該指針所指向的內容,一旦一方修改,另一方也會受到影響。
  • 參數傳遞不同:雖然函數的參數都是按值傳遞的,但是引用值傳遞的值是一個內存地址,實參和形參指向的是同一個對象,所以函數內部對這個參數的修改會體現在外部。原始值只是把變量里的值傳遞給參數,之后參數和這個變量互不影響。

7.深拷貝和淺拷貝

區別 www.cnblogs.com/echolun/p/7…

深拷貝的方法 www.cnblogs.com/Mrrabbit/p/…

8.解釋一下原型繼承的原理

參考:www.cnblogs.com/syfwhu/p/44…

9.解釋下為什么接下來這段代碼不是IIFE(立即調用的函數表達式):

function foo(){
    //code
}()

 

 

以function關鍵字開頭的語句會被解析為函數聲明,而函數聲明是不允許直接運行的。 只有當解析器把這句話解析為函數表達式,才能夠直接運行,怎么辦呢?以運算符開頭就可以了。

(function foo(){
    // code..
})()

 

 

10.請盡可能詳盡的解釋AJAX的工作原理

ajax簡單來說是通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然后用javascript來操作DOM而更新頁面。

ajax的優點

  • 最大的一點是頁面無刷新,在頁面內與服務器通信,給用戶的體驗非常好。
  • 使用異步方式與服務器通信,不需要打斷用戶的操作,具有更加迅速的響應能力。
  • 可以把以前一些服務器負擔的工作轉嫁到客戶端,利用客戶端閑置的能力來處理,減輕服務器和帶寬的負擔,節約空間和寬帶租用成本,ajax的原則是“按需取數據”,可以最大程度的減少冗余請求。
  • 基於標准化的並被廣泛支持的技術,不需要下載插件或者小程序。

ajax的缺點

  • ajax對瀏覽器后退機制造成了破壞,也就是說用戶無法通過瀏覽器的后退按鈕回到前一次操作的頁面。雖然有些瀏覽器解決了這個問題,比如Gmail,但它也並不能改變ajax的機制,它所帶來的開發成本是非常高的,和ajax框架所要求的快速開發是相背離的。這是ajax所帶來的一個非常嚴重的問題。
  • 安全問題。技術同時也對IT企業帶來了新的安全威脅,ajax技術就如同對企業數據建立了一個直接通道。這使得開發者在不經意間會暴露比以前更多的數據和服務器邏輯。
  • 對搜索引擎的支持比較弱。
  • 破壞了程序的異常機制。至少從目前看來,像ajax.dll,ajaxpro.dll這些ajax框架是會破壞程序的異常機制的。關於這個問題,我曾經在開發過程中遇到過,但是查了一下網上幾乎沒有相關的介紹。后來我自己做了一次試驗,分別采用ajax和傳統的form提交的模式來刪除一條數據……給我們的調試帶來了很大的困難。
  • 另外,像其他方面的一些問題,比如說違背了url和資源定位的初衷。例如,我給你一個url地址,如果采用了ajax技術,也許你在該url地址下面看到的和我在這個url地址下看到的內容是不同的。這個和資源定位的初衷是相背離的。
  • 一些手持設備(如手機、PDA等)現在還不能很好的支持ajax,比如說我們在手機的瀏覽器上打開采用ajax技術的網站時,它目前是不支持的,當然,這個問題和我們沒太多關系。

11.get和post有什么區別?

其實,GET和POST本質上兩者沒有任何區別。他們都是HTTP協議中的請求方法。底層實現都是基於TCP/IP協議。所謂區別,只是瀏覽器廠家根據約定,做得限制而已。

  • get是通過明文發送數據請求,而post是通過密文;
  • get傳輸的數據量有限,因為url的長度有限,post則不受限;
  • GET請求的參數只能是ASCII碼,所以中文需要URL編碼,而POST請求傳參沒有這個限制
  • GET產生一個TCP數據包;POST產生兩個TCP數據包。對於GET方式的請求,瀏覽器會把http header和data一並發送出去,服務器響應200(返回數據);而對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。
  • 參考:www.cnblogs.com/logsharing/…

12.請解釋變量聲明提升

通過var聲明的變量會被提升至作用域的頂端。不僅僅是變量,函數聲明也一樣會被提升。當同一作用域內同時出現變量和函數聲明提升時,變量仍然在函數前面。 參考:www.cnblogs.com/guanhuachen…

13.請指出document.onload和document.ready兩個事件的區別

頁面加載完成有兩種事件,一是ready,表示文檔結構已經加載完成(不包含圖片等非文字媒體文件),二是onload,指示頁面包含圖片等文件在內的所有元素都加載完成。

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

getUrlParam : function(name){
        //baidu.com/product/list?keyword=XXX&page=1
        var reg     = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
        var result  = window.location.search.substr(1).match(reg);
        return result ? decodeURIComponent(result[2]) : null;
    }

 

 

 

 


 

  • 首先設置一個函數,給這個函數傳遞一個參數,也就是url的search部分的key值;
  • 設置一個正則表達式,以&開頭或沒有,中間是參數,后面以#或&結尾或沒有;
  • 通過window.location.search.substr(1).match()匹配,返回一個數組
  • 如果數組不為空,返回數組的第3個值,也就是正則表達式的第二個子串

15.什么是三元表達式?“三元”表示什么意思?

三元表達式:? :。三元--三個操作對象。

在表達式boolean-exp ? value0 : value1 中,如果“布爾表達式”的結果為true,就計算“value0”,而且這個計算結果也就是操作符最終產生的值。如果“布爾表達式”的結果為false,就計算“value1”,同樣,它的結果也就成為了操作符最終產生的值。

16.JavaScript里arguments究竟是什么?

Javascrip中國每個函數都會有一個Arguments對象實例arguments,它引用着函數的實參,可以用數組下標的方式"[]"引用arguments的元素。arguments.length為函數實參個數,arguments.callee引用函數自身。

在函數代碼中,使用特殊對象arguments,開發者無需明確指出參數名,通過使用下標就可以訪問相應的參數。

function test() {
        var s = "";
        for (var i = 0; i < arguments.length; i++) {
            alert(arguments[i]);
            s += arguments[i] + ",";
        }
        return s;
    }
    test("name", "age");//name,age

 

 

arguments雖然有一些數組的性質,但其並非真正的數組,只是一個類數組對象。其並沒有數組的很多方法,不能像真正的數組那樣調用.jion(),.concat(),.pop()等方法。

 

17.什么是"use strict";?使用它的好處和壞處分別是什么?

在代碼中出現表達式-"use strict"; 意味着代碼按照嚴格模式解析,這種模式使得Javascript在更嚴格的條件下運行。

好處:

  • 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全;
  • 提高編譯器效率,增加運行速度;
  • 為未來新版本的Javascript做好鋪墊。

壞處:

  • 同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;
  • 一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行。

18.請解釋一下JavaScript的同源策略

同源策略,即擁有相同的協議(protocol),端口(如果指定),主機(域名)的兩個頁面是屬於同一個源。 然而在IE中比較特殊,IE中沒有將端口號加入同源的條件中,因此上圖中端口不同那一項,在IE中是算同源的。 <script> <img> <iframe>中的src,href都可以任意鏈接網絡資源,是不遵循通源策略的。

19.請解釋JSONP的工作原理,以及它為什么不是真正的AJAX。

JSONP (JSON with Padding)是一個簡單高效的跨域方式,HTML中的script標簽可以加載並執行其他域的javascript,於是我們可以通過script標記來動態加載其他域的資源。例如我要從域A的頁面pageA加載域B的數據,那么在域B的頁面pageB中我以JavaScript的形式聲明pageA需要的數據,然后在 pageA中用script標簽把pageB加載進來,那么pageB中的腳本就會得以執行。JSONP在此基礎上加入了回調函數,pageB加載完之后會執行pageA中定義的函數,所需要的數據會以參數的形式傳遞給該函數。JSONP易於實現,但是也會存在一些安全隱患,如果第三方的腳本隨意地執行,那么它就可以篡改頁面內容,截獲敏感數據。但是在受信任的雙方傳遞數據,JSONP是非常合適的選擇。

AJAX是不跨域的,而JSONP是一個是跨域的,還有就是二者接收參數形式不一樣!

20.通過new創建一個對象的時候,構造函數內部有哪些改變?

function Person(){}
Person.prototype.friend = [];
Person.prototype.name = '';
var a = new Person();
a.friend[0] = '王琦';
var b = new Person();
console.log(b.friend);//Array [ "王琦" ]

 

 
  • 創建一個空對象,並且 this 變量引用該對象,同時還繼承了該函數的原型。
  • 屬性和方法被加入到 this 引用的對象中。
  • 新創建的對象由 this 所引用,並且最后隱式的返回 this 。

22.什么是跨域?有什么方法解決跨域帶來的問題?

跨域需要針對瀏覽器的同源策略來理解,同源策略指的是請求必須是同一個端口,同一個協議,同一個域名,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源。

受瀏覽器同源策略的影響,不是同源的腳本不能操作其他源下面的對象。想要操作另一個源下的對象是就需要跨域。

解決方法: jsonp

關於定時器的那些事兒~(偏小白邏輯)

1.如果用戶持續點擊一個按鈕,如何只提交一次請求,且不影響后續使用?(其實就是如何節流這個真的問的好多!!!!)

    function conso(){
          console.log('is run');
      }
      var btnUse=true;
     $("#btn").click(function(){
         if(btnUse){
             conso();
             btnUse=false;
         }
         setTimeout(function(){
             btnUse=true;
         },1500) //點擊后相隔多長時間可執行
     })

 

 

2.猜猜如下題目的結果?

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  setInterval(() => this.s1++, 1000);
  setInterval(function () {
    this.s2++;
  }, 1000);
}

var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);

 

 

答案是:

s1: 3
s2: 0

 



等我面完試回來講原因……

順便,今天上午面試,筆試題基本都沒問題,但面試官突然發現我是轉行的沒有工作經歷,於是禮貌的感謝了我,涼涼~~~有什么辦法解決沒有工作經歷這個硬傷嗎??


作者:梭梭醬加油鴨
鏈接:https://juejin.im/post/5c9216716fb9a070ef60a011
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM