前端開發面試題之 JavaScript


 

「每18至24個月,前端都會難一倍」javascript

——赫門 「2015深js大會《前端服務化之路》主題演講」html

知識點

數據類型運算對象function繼承閉包做用域原型鏈事件RegExpJSONAjaxDOMBOM內存泄漏跨域異步加載模板引擎前端MVC前端MVVM路由模塊化CanvasjQueryECMAScript 2015(ES6)Node.jsAngularJSReactCommonJSAMDCMD ......前端

題目&答案

  • 介紹一下 JS 的基本數據類型。
    Undefined、Null、Boolean、Number、String
  • 介紹一下 JS 有哪些內置對象。
    Object 是 JavaScript 中全部對象的父對象 數據封裝類對象:Object、Array、Boolean、Number、String 其餘對象:Function、Argument、Math、Date、RegExp、Error
  • 列舉幾條 JavaScript 的基本代碼規範。
    1)不要在同一行聲明多個變量 (2)若是你不知道數組的長度,使用 push (3)請使用 ===/!== 來比較 true/false 或者數值 (4)對字符串使用單引號 ''(由於大多時候咱們的字符串。特別html會出現") (5)使用對象字面量替代 new Array 這種形式 (6)絕對不要在一個非函數塊裏聲明一個函數,把那個函數賦給一個變量。瀏覽器容許你這麼作,可是它們解析不一樣 (7)不要使用全局函數 (8)老是使用 var 來聲明變量,若是不這麼作將致使產生全局變量,咱們要避免污染全局命名空間 (9)Switch 語句必須帶有 default 分支 (10)使用 /**...*/ 進行多行註釋,包括描述,指定類型以及參數值和返回值 (11)函數不該該有時候有返回值,有時候沒有返回值 (12)語句結束必定要加分號 (13)for 循環必須使用大括號 (14)if 語句必須使用大括號 (15)for-in 循環中的變量應該使用 var 關鍵字明確限定做用域,從而避免做用域污染 (16)避免單個字符名,讓你的變量名有描述意義 (17)當命名對象、函數和實例時使用駝峯命名規則 (18)給對象原型分配方法,而不是用一個新的對象覆蓋原型,覆蓋原型會使繼承出現問題 (19)當給事件附加數據時,傳入一個哈希而不是原始值,這可讓後面的貢獻者加入更多數據到事件數據裏,而不用找出並更新那個事件的事件處理器
  • 介紹一下 JavaScript 原型,原型鏈,它們有何特色?
    每一個對象都會在其內部初始化一個屬性,就是prototype(原型),當咱們訪問一個對象的屬性時,若是這個對象內部不存在這個屬性,那麼他就會去prototype裏找這個屬性,這個prototype又會有本身的prototype,
    因而就這樣一直找下去,也就是咱們平時所說的原型鏈的概念。
    關係:instance.constructor.prototype = instance.__proto__
    // 特色:JavaScript對象是經過引用來傳遞的,咱們建立的每一個新對象實體中並無一份屬於本身的原型副本,當咱們修改原型時,與之相關的對象也會繼承這一改變。 // 當咱們須要一個屬性時,JavaScript引擎會先看當前對象中是否有這個屬性,若是沒有的話,就會查找它的prototype對象是否有這個屬性,如此遞推下去,一致檢索到Object內建對象。 function Func(){} Func.prototype.name = "Xiaosong"; Func.prototype.getInfo = function() { return this.name; } var person = new Func(); console.log(person.getInfo()); //"Xiaosong" console.log(Func.prototype); //Func { name = "Xiaosong", getInfo = function() }
  • JavaScript 有幾種類型的值?可否畫一下它們的內存圖?
    棧:原始數據類型(Undefined,Null,Boolean,Number,String) 堆:引用數據類型(對象、數組、函數) 兩種類型的區別:存儲位置不一樣 // 原始數據類型直接存儲在棧(stack)中的簡單數據段,佔據空間小、大小固定,屬於被頻繁使用數據,因此放入棧中存儲; 引用數據類型存儲在堆(heap)中的對象,佔據空間大、大小不固定,若是存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址後從堆中得到實體。
  • JavaScript 如何實現繼承?
    (1)構造繼承 (2)原型繼承 (3)實例繼承 (4)拷貝繼承 // 原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式。 function Parent() { this.name = 'song'; } function Child() { this.age = 28; } Child.prototype = new Parent(); //經過原型,繼承了Parent // var demo = new Child()l; alert(demo.age); alert(demo.name); //獲得被繼承的屬性
  • JavaScript 有哪幾種建立對象的方式?
    javascript建立對象簡單的說,無非就是使用內置對象或各類自定義對象,固然還能夠用JSON;但寫法有不少種,也能混合使用。 // (1)對象字面量的方式 person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"}; (2)用function來模擬無參的構造函數 function Person(){} var person = new Person(); //定義一個function,若是使用new"實例化",該function能夠看做是一個Class person.name = "Xiaosong"; person.age = "23"; person.work = function() { alert("Hello " + person.name); } person.work(); (3)用function來模擬參構造函數來實現(用this關鍵字定義構造的上下文屬性) function Person(name,age,hobby) { this.name = name; //this做用域:當前對象 this.age = age; this.work = work; this.info = function() { alert("我叫" + this.name + ",今年" + this.age + "歲,是個" + this.work); } } var Xiaosong = new Person("WooKong",23,"程序猿"); //實例化、建立對象 Xiaosong.info(); //調用info()方法 (4)用工廠方式來建立(內置對象) var jsCreater = new Object(); jsCreater.name = "Brendan Eich"; //JavaScript的發明者 jsCreater.work = "JavaScript"; jsCreater.info = function() { alert("我是"+this.work+"的發明者"+this.name); } jsCreater.info(); (5)用原型方式來建立 function Standard(){} Standard.prototype.name = "ECMAScript"; Standard.prototype.event = function() { alert(this.name+"是腳本語言標準規範"); } var jiaoben = new Standard(); jiaoben.event(); (6)用混合方式來建立 function iPhone(name,event) { this.name = name; this.event = event; } iPhone.prototype.sell = function() { alert("我是"+this.name+",我是iPhone5s的"+this.event+"~ haha!"); } var SE = new iPhone("iPhone SE","官方翻新機"); SE.sell();
  • eval 是作什麼的?
    它的功能是把對應的字符串解析成JS代碼並運行;
    應該避免使用eval,由於不安全,很是耗性能(2次,一次解析成js語句,一次執行)。
  • 什麼是 document 對象?什麼是 window 對象?
  • null 和 undefined 有何區別?
    null 表示一個對象被定義了,值爲「空值」; undefined 表示不存在這個值。 // typeof undefined //"undefined" undefined :是一個表示"無"的原始值或者說表示"缺乏值",就是此處應該有一個值,可是尚未定義。當嘗試讀取時會返回 undefined; 例如變量被聲明瞭,但沒有賦值時,就等於undefined。 // typeof null //"object" null : 是一個對象(空對象, 沒有任何屬性和方法); 例如做爲函數的參數,表示該函數的參數不是對象; // 注意: 在驗證null時,必定要使用 === ,由於 == 沒法分別 null 和 undefined
  • 可否寫一個通用的事件偵聽器函數?
    //Event工具集,from:github.com/markyun markyun.Event = { //頁面加載完成後 readyEvent: function(fn) { if (fn == null) { fn = document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; }else{ window.onload = function() { oldonload(); fn(); }; } }, //視能力分別使用 demo0 || demo1 || IE 方式來綁定事件 //參數:操做的元素,事件名稱,事件處理程序 addEvent: function(element,type,handler) { if (element.addEventListener) { //事件類型、須要執行的函數、是否捕捉 element.addEventListener(type,handler,false); }else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); }else { element['on' + type] = handler; } }, //移除事件 removeEvent: function(element,type,handler) { if (element.removeEventListener) { element.removeEventListener(type,handler,false); }else if (element.datachEvent) { element.datachEvent('on' + type,handler); }else{ element['on' + type] = null; } }, //阻止事件(主要是事件冒泡,由於IE不支持事件捕獲) stopPropagation: function(ev) { if (ev.stopPropagation) { ev.stopPropagation(); }else { ev.cancelBubble = true; } }, //取消事件的默認行爲 preventDefault: function(event) { if (event.preventDefault) { event.preventDefault(); }else{ event.returnValue = false; } }, //獲取事件目標 getTarget: function(event) { return event.target || event.srcElemnt; }, //獲取event對象的引用,取到事件的全部信息,確保隨時能使用event; getEvent: function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while(c) { ev = c.argument[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } retrun ev; } };
  • ["1","2","3"].map(parseInt) 的答案是多少?
    [1,NaN,NaN] 由於 parseInt 須要兩個參數(val,radix),其中 radix 表示解析時用的基數。 map 傳了3個(element,index,array),對應的 radix 不合法致使解析失敗。
  • 事件是什麼?IE與火狐的事件機制有何區別?如何阻止冒泡?
    (1)咱們在網頁中的某個操做(有的操做對應多個事件)。例如:當咱們點擊一個按鈕就會產生一個事件。是能夠被 JavaScript 偵測到的行爲。 (2)事件處理機制:IE是事件冒泡、Firefox同時支持兩種事件模型,也就是:捕獲型事件和冒泡型事件; (3)ev.stopPropagation();(舊ie的方法 ev.cancelBubble = true;)
  • 什麼是閉包(closure),爲何要用它?
    閉包是指有權訪問另外一個函數做用域中變量的函數,建立閉包的最多見的方式就是在一個函數內建立另外一個函數,經過另外一個函數訪問這個函數的局部變量,利用閉包能夠突破做用鏈域,將函數內部的變量和方法傳遞到外部。
    //
    閉包特性:
    (1)函數內再嵌套函數
    (2)內部函數能夠引用外層的參數和變量
    (3)參數和變量不會被垃圾回收機制回收
    //li節點的onclick事件都能正確的彈出當前被點擊的li索引
    <ul> <li> index = 0 </li> <li> index = 1 </li> <li> index = 2 </li> <li> index = 3 </li> </ul> <script type="text/javascript"> var nodes = document.getElementsByTagName('li'); for(i = 0;i<nodes.length;i+=1) { nodes[i].onclick = function() { console.log(i+1); //不使用閉包的話,值每次都是4 }(4); } </script>
  • JavaScript 代碼中的 "use strict"; 是什麼意思?使用它的區別是什麼?
    use strict是一種ECMAscript 5 添加的(嚴格)運行模式,這種模式使得 Javascript 在更嚴格的條件下運行,使JS編碼更加規範化的模式,消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲。 默認支持的糟糕特性都會被禁用,好比不能用with,也不能在乎外的狀況下給全局變量賦值; 全局變量的顯示聲明,函數必須聲明在頂層,不容許在非函數代碼塊內聲明函數,arguments.callee也不容許使用; 消除代碼運行的一些不安全之處,保證代碼運行的安全,限制函數中的arguments修改,嚴格模式下的eval函數的行爲和非嚴格模式的也不相同; 提升編譯器效率,增長運行速度; 爲將來新版本的Javascript標準化作鋪墊。
  • new 操做符具體幹了什麼呢?
    (1)建立一個空對象,而且 this 變量引用該對象,同時還繼承了該函數的原型。 (2)屬性和方法被加入到 this 引用的對象中。 (3)新建立的對象由 this 所引用,而且最後隱式的返回 this 。 // var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj);
  • 用原生的 JavaScript 實現過什麼功能嗎?
  • JavaScript 中,有一個函數,執行對象查找時,永遠不會去查找原型,這個函數是哪一個?
    hasOwnProperty
    // JavaScript 中 hasOwnProperty 函數方法是返回一個布爾值,指出一個對象是否具備指定名稱的屬性。此方法沒法檢查該對象的原型鏈中是否具備該屬性;該屬性必須是對象自己的一個成員。 // 使用方法: object.hasOwnProperty(proName) 其中參數object是必選項,一個對象的實例。 proName是必選項,一個屬性名稱的字符串值。 // 若是 object 具備指定名稱的屬性,那麼JavaScript中hasOwnProperty函數方法返回 true,反之則返回 false。
  • 你對 JSON 瞭解嗎?
    JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。 它是基於JavaScript的一個子集。數據格式簡單,易於讀寫,佔用帶寬小。 如: {"age":"12", "name":"back"}
  • js延遲加載的方式有哪些?
    defer和async、動態建立DOM方式(用得最多)、按需異步載入js
  • Ajax 是什麼?如何建立一個 Ajax ?
    ajax的全稱:Asynchronous Javascript And XML。
    異步傳輸+js+xml。
    所謂異步,在這裏簡單地解釋就是:向服務器發送請求的時候,咱們沒必要等待結果,而是能夠同時作其餘的事情,等到有告終果它本身會根據設定進行後續操做,與此同時,頁面是不會發生整頁刷新的,提升了用戶體驗。
    // (1)建立XMLHttpRequest對象,也就是建立一個異步調用對象 (2)建立一個新的HTTP請求,並指定該HTTP請求的方法、URL及驗證信息 (3)設置響應HTTP請求狀態變化的函數 (4)發送HTTP請求 (5)獲取異步調用返回的數據 (6)使用JavaScript和DOM實現局部刷新
  • 同步和異步的區別?
    同步的概念應該是來自於操做系統中關於同步的概念:
    不一樣進程爲協同完成某項工做而在前後次序上調整(經過阻塞,喚醒等方式)。同步強調的是順序性,誰先誰後;異步則不存在這種順序性。
    // 同步:瀏覽器訪問服務器請求,用戶看獲得頁面刷新,從新發請求,等請求完,頁面刷新,新內容出現,用戶看到新內容,進行下一步操做。 // 異步:瀏覽器訪問服務器請求,用戶正常操做,瀏覽器後端進行請求。等請求完,頁面不刷新,新內容也會出現,用戶看到新內容。
  • 如何解決跨域問題?
    jsonp、iframe、window.name、window.postMessage、服務器上設置代理頁面
  • 頁面編碼和被請求的資源編碼若是不一致如何處理?
  • 談一談你對 ECMAScript6 的瞭解?
    ECMAScript 6 是JavaScript語言的下一代標準,已經在2015年6月正式發佈了。它的目標,是使得JavaScript語言能夠用來編寫複雜的大型應用程序,成爲企業級開發語言。 標準的制定者有計劃,之後每一年發佈一次標準,使用年份做爲標準的版本。由於當前版本的ES6是在2015年發佈的,因此又稱ECMAScript 2015。也就是說,ES6就是ES2015
  • ECMAScript 6 怎麼寫 class ,爲什麼會出現 class?
    ES6的class能夠看做只是一個語法糖,它的絕大部分功能,ES5均可以作到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。 //定義類 class Point { constructor(x,y) { //構造方法 this.x = x; //this關鍵字表明實例對象 this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } }
  • 異步加載 JS 的方式有哪些?
    (1)defer,只支持 IE (2)async: (3)建立 script,插入到 DOM 中,加載完畢後 callBack
  • document.write 和 innerHTML 有何區別?
    document.write 只能重繪整個頁面 innerHTML 能夠重繪頁面的一部分
  • DOM 操做——怎樣添加、移除、移動、複製、建立和查找節點?
    (1)建立新節點 createDocumentFragment() //建立一個DOM片斷 createElement() //建立一個具體的元素 createTextNode() //建立一個文本節點 (2)添加、移除、替換、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子節點前插入一個新的子節點 (3)查找 getElementsByTagName() //經過標籤名稱 getElementsByName() //經過元素的Name屬性的值(IE容錯能力較強,會獲得一個數組,其中包括id等於name值的) getElementById() //經過元素Id,惟一性
  • 數組和對象有哪些原生方法?可否列舉一下?
  • 哪些操做會形成內存泄漏?
    內存泄漏是指任何對象在您再也不擁有或須要它以後任然存在。
    垃圾回收器按期掃描對象,並計算引用了每一個對象的其餘對象的數量,若是一個對象的引用數量爲0(沒有其餘對象引用過該對象),或對該對象的唯一引用是循環的,那麼該對象的內存便可回收。 // setTimeout 的第一個參數使用字符串而非函數的話,會引起內存泄漏。 閉包、控制檯日誌、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)
  • 是否看過 jQuery 的源碼?可否簡單歸納一下它的實現原理?
  • jQuery.fn 的 init 方法返回的 this 指的是什麼對象?爲何要返回 this ?
  • jQuery 中如何將數組轉化爲 json 字符串,而後再轉化回來?
    jQuery 中沒有提供這個功能,因此須要先編寫兩個 jQuery 的擴展:
    $.fn.stringifyArray = function(array) { return JSON.stringify(array) } $.fn.parseArray = function(array) { return JSON.parse(array) } // 而後調用: $("").stringifyArray(array)
  • jQuery 的屬性拷貝(extend)的實現原理是什麼?如何實現深拷貝?
  • jQuery.extend 與 jQuery.fn.extend 有何區別?
  • jQuery 的隊列是如何實現的?隊列能夠用在哪些地方?
  • jQuery 中一個對象能夠同時綁定多個事件,這是如何實現的?
  • 是否瞭解針對 jQuery 性能的優化方法?
    基於Class的選擇性的性能相對於Id選擇器開銷很大,由於需遍歷全部DOM元素。
    // 頻繁操做的DOM,先緩存起來再操做。用Jquery的鏈式調用更好。 好比:var str=$("a").attr("href"); // for (var i = size; i < arr.length; i++) {} for 循環每一次循環都查找了數組 (arr) 的.length 屬性,在開始循環的時候設置一個變量來存儲這個數字,可讓循環跑得更快: for (var i = size, length = arr.length; i < length; i++) {}
  • jQuery 與 jQuery UI 有何區別?
    `jQuery`是一個js庫,主要提供的功能是選擇器,屬性修改和事件綁定等等。 `jQuery UI`則是在jQuery的基礎上,利用jQuery的擴展性,設計的插件。提供了一些經常使用的界面元素,諸如對話框、拖動行爲、改變大小行爲等等
  • jQuery UI 如何自定義組件?
  • 如何判斷當前腳本運行在瀏覽器仍是 node 環境中?(阿里)
    經過判斷 Global 對象是否爲 window ,若是不爲 window ,當前腳本沒有運行在瀏覽器中
  • 什麼是「前端路由」?何時適合使用「前端路由」?「前端路由」有哪些優勢和缺點?
  • 怎樣用js實現千位分隔符?
    正則 + replace
    function commafy(num) { num = num + ''; var reg = /(-?d+)(d{3})/; if (reg.test(num)) { num = num.replace(reg, '$1,$2'); } return num; }
  • 檢測瀏覽器版本有哪些方式?
    功能檢測、userAgent 特徵檢測
    好比:navigator.userAgent //"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
  • 前端 MVC、MVVM
    一、MVC

    MVC
    模型(Model):數據保存
    視圖(View):用戶界面
    控制器(Controller):業務邏輯
    (1)View 傳送指令到 Controller (2)Controller 完成業務邏輯後,要求 Model 改變狀態 (3)Model 將新的數據發送到 View ,用戶獲得反饋 全部通訊都是單向的。
    二、MVVM

    MVVM
    模型(Model)
    視圖(View)
    視圖模型(ViewModel)
    (1)各部分間都是雙向通訊 (2)View 與 Model 不發生聯繫,都經過 ViewModel 傳遞 (3)View 很是薄,不部署任何業務邏輯,稱爲「被動視圖」(Passive View),即沒有任何主動性;而 ViewModel 很是厚,全部邏輯都部署在那裏 採用雙向綁定(data-binding):View 的變更,自動反映在 ViewModel ,反之亦然。
相關文章
相關標籤/搜索