Javascript面試題

一、簡述同步和異步的區別 

  • 同步是阻塞模式,異步是非阻塞模式。 
  • 同步就是指一個進程在執行某個請求的時候,若該請求須要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去; 
  • 異步是指進程不須要一直等下去,而是繼續執行下面的操做,無論其餘進程的狀態。當有消息返回時系統會通知進程進行處理,這樣能夠提升執行的效率。

二、web前端開發,如何提升頁面性能優化? 

內容方面:javascript

1. 減小 HTTP 請求 (Make Fewer HTTP Requests)
php

2. 減小 DOM 元素數量 (Reduce the Number of DOM Elements) css

3. 使得 Ajax 可緩存 (Make Ajax Cacheable) html

針對CSS: 前端

1. 把 CSS 放到代碼頁上端 (Put Stylesheets at the Top) java

2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External) webpack

3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS) 程序員

4. 避免 CSS 表達式 (Avoid CSS Expressions)  web

針對JavaScript : ajax

1. 腳本放到 HTML 代碼頁底部 (Put Scripts at the Bottom) 

2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External) 

3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS) 

4. 移除重複腳本 (Remove Duplicate Scripts) 

面向圖片(Image): 

1. 優化圖片 

2. 不要在 HTML 中使用縮放圖片 

3. 使用恰當的圖片格式 

4. 使用 CSS Sprites 技巧對圖片優化

三、考慮如下兩個函數。它們會返回相同的東西嗎? 爲何相同或爲何不相同?

function foo1(){  return {
      bar: "hello"
  };
}

function foo2(){  return
  {
      bar: "hello"
  };
}複製代碼

出人意料的是,這兩個函數返回的內容並不相同。更確切地說是:

console.log("foo1 returns:");console.log(foo1());console.log("foo2 returns:");console.log(foo2());複製代碼

將產生:

foo1 returns:Object {bar: "hello"}foo2 returns:undefined複製代碼

這不只是使人驚訝,並且特別讓人困惑的是, foo2()返回undefined卻沒有任何錯誤拋出。

緣由與這樣一個事實有關,即分號在JavaScript中是一個可選項(儘管省略它們一般是很是糟糕的形式)。其結果就是,當碰到 foo2()中包含 return語句的代碼行(代碼行上沒有其餘任何代碼),分號會當即自動插入到返回語句以後。

也不會拋出錯誤,由於代碼的其他部分是徹底有效的,即便它沒有獲得調用或作任何事情(至關於它就是是一個未使用的代碼塊,定義了等同於字符串 "hello"的屬性 bar)。

這種行爲也支持放置左括號於JavaScript代碼行的末尾,而不是新代碼行開頭的約定。正如這裏所示,這不只僅只是JavaScript中的一個風格偏好。

四、閉包

  • 閉包就是可以讀取其餘函數內部變量的函數

  • 閉包是指有權訪問另外一個函數做用域中變量的函數,建立閉包的最多見的方式就是在一個函數內建立另外一個函數,經過另外一個函數訪問這個函數的局部變量,利用閉包能夠突破做用鏈域

  • 閉包的特性:

    • 函數內再嵌套函數
    • 內部函數能夠引用外層的參數和變量
    • 參數和變量不會被垃圾回收機制回收

說說你對閉包的理解

  • 使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。在js中,函數即閉包,只有函數纔會產生做用域的概念

  • 閉包 的最大用處有兩個,一個是能夠讀取函數內部的變量,另外一個就是讓這些變量始終保持在內存中

  • 閉包的另外一個用處,是封裝對象的私有屬性和私有方法

  • 好處:可以實現封裝和緩存等;

  • 壞處:就是消耗內存、不正當使用會形成內存溢出的問題

使用閉包的注意點

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

五、說說你對做用域鏈的理解

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

六、JavaScript原型,原型鏈 ? 有什麼特色?

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

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

  • 關係:instance.constructor.prototype = instance.__proto__

  • 特色:

    • JavaScript對象是經過引用來傳遞的,咱們建立的每一個新對象實體中並無一份屬於本身的原型副本。當咱們修改原型時,與之相關的對象也會繼承這一改變
  • 當咱們須要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性, 若是沒有的

  • 就會查找他的Prototype對象是否有這個屬性,如此遞推下去,一直檢索到 Object 內建對象

七、請解釋什麼是事件代理

  • 事件代理(Event Delegation),又稱之爲事件委託。是 JavaScript 中經常使用綁定事件的經常使用技巧。顧名思義,「事件代理」便是把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好處是能夠提升性能
  • 能夠大量節省內存佔用,減小事件註冊,好比在table上代理全部tdclick事件就很是棒
  • 能夠實現當新增子對象時無需再次對其綁定

八、Javascript如何實現繼承?

  • 構造繼承

  • 原型繼承

  • 實例繼承

  • 拷貝繼承

  • 原型prototype機制或applycall方法去實現較簡單,建議使用構造函數與原型混合方式

function Parent(){
        this.name = 'wang';
    }

    function Child(){
        this.age = 28;
    }
    Child.prototype = new Parent();//繼承了Parent,經過原型

    var demo = new Child();
    alert(demo.age);
    alert(demo.name);//獲得被繼承的屬性
  }
複製代碼

九、談談This對象的理解

  • this老是指向函數的直接調用者(而非間接調用者)
  • 若是有new關鍵字,this指向new出來的那個對象
  • 在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this老是指向全局對象Window

十、事件模型

W3C中定義事件的發生經歷三個階段:捕獲階段(capturing)、目標階段(targetin)、冒泡階段(bubbling

  • 冒泡型事件:當你使用事件冒泡時,子級元素先觸發,父級元素後觸發
  • 捕獲型事件:當你使用事件捕獲時,父級元素先觸發,子級元素後觸發
  • DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件
  • 阻止冒泡:在W3c中,使用stopPropagation()方法;在IE下設置cancelBubble = true
  • 阻止捕獲:阻止事件的默認行爲,例如click - <a>後的跳轉。在W3c中,使用preventDefault()方法,在IE下設置window.event.returnValue = false

十一、new操做符具體幹了什麼呢?

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

十二、Ajax原理

  • Ajax的原理簡單來講是在用戶和服務器之間加了—箇中間層(AJAX引擎),經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。使用戶操做與服務器響應異步化。這其中最關鍵的一步就是從服務器得到請求數據
  • Ajax的過程只涉及JavaScriptXMLHttpRequestDOMXMLHttpRequestajax的核心機制
// 1. 建立鏈接
    var xhr = null;
    xhr = new XMLHttpRequest()
    // 2. 鏈接服務器
    xhr.open('get', url, true)
    // 3. 發送請求
    xhr.send(null);
    // 4. 接受請求
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                success(xhr.responseText);
            } else { // fail
                fail && fail(xhr.status);
            }
        }
    }
複製代碼

ajax 有那些優缺點?

  • 優勢:
    • 經過異步模式,提高了用戶體驗.
    • 優化了瀏覽器和服務器之間的傳輸,減小沒必要要的數據往返,減小了帶寬佔用.
    • Ajax在客戶端運行,承擔了一部分原本由服務器承擔的工做,減小了大用戶量下的服務器負載。
    • Ajax能夠實現動態不刷新(局部刷新)
  • 缺點:
    • 安全問題 AJAX暴露了與服務器交互的細節。
    • 對搜索引擎的支持比較弱。
    • 不容易調試。

1三、如何解決跨域問題?

  • jsonpiframewindow.namewindow.postMessage、服務器上設置代理頁面

1四、模塊化開發怎麼作?

  • 當即執行函數,不暴露私有成員
var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
複製代碼

1五、異步加載JS的方式有哪些?

  • defer,只支持IE
  • async
  • 建立script,插入到DOM中,加載完畢後callBack

1六、那些操做會形成內存泄漏?

  • 內存泄漏指任何對象在您再也不擁有或須要它以後仍然存在
  • setTimeout 的第一個參數使用字符串而非函數的話,會引起內存泄漏
  • 閉包使用不當

1七、XML和JSON的區別?

  • 數據體積方面

    • JSON相對於XML來說,數據的體積小,傳遞的速度更快些。
  • 數據交互方面

    • JSONJavaScript的交互更加方便,更容易解析處理,更好的數據交互
  • 數據描述方面

    • JSON對數據的描述性比XML較差
  • 傳輸速度方面

    • JSON的速度要遠遠快於XML

1八、談談你對webpack的見解

  • WebPack 是一個模塊打包工具,你可使用WebPack管理你的模塊依賴,並編繹輸出模塊們所需的靜態文件。它可以很好地管理、打包Web開發中所用到的HTMLJavascriptCSS以及各類靜態文件(圖片、字體等),讓開發過程更加高效。對於不一樣類型的資源,webpack有對應的模塊加載器。webpack模塊打包器會分析模塊間的依賴關係,最後 生成了優化且合併後的靜態資源

1九、說說你對AMD和Commonjs的理解

  • CommonJS是服務器端模塊的規範,Node.js採用了這個規範。CommonJS規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操做。AMD規範則是非同步加載模塊,容許指定回調函數
  • AMD推薦的風格經過返回一個對象作爲模塊對象,CommonJS的風格經過對module.exportsexports的屬性賦值來達到暴露模塊對象的目的

20、常見web安全及防禦原理

  • sql注入原理

    • 就是經過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令
  • 總的來講有如下幾點

    • 永遠不要信任用戶的輸入,要對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度,對單引號和雙"-"進行轉換等
    • 永遠不要使用動態拼裝SQL,可使用參數化的SQL或者直接使用存儲過程進行數據查詢存取
    • 永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接
    • 不要把機密信息明文存放,請加密或者hash掉密碼和敏感的信息

XSS原理及防範

  • Xss(cross-site scripting)攻擊指的是攻擊者往Web頁面裏插入惡意html標籤或者javascript代碼。好比:攻擊者在論壇中放一個看似安全的連接,騙取用戶點擊後,竊取cookie中的用戶私密信息;或者攻擊者在論壇中加一個惡意表單,當用戶提交表單的時候,卻把信息傳送到攻擊者的服務器中,而不是用戶本來覺得的信任站點

XSS防範方法

  • 首先代碼裏對用戶輸入的地方和變量都須要仔細檢查長度和對」<」,」>」,」;」,」’」等字符作過濾;其次任何內容寫到頁面以前都必須加以encode,避免不當心把html tag 弄出來。這一個層面作好,至少能夠堵住超過一半的XSS 攻擊

XSS與CSRF有什麼區別嗎?

  • XSS是獲取信息,不須要提早知道其餘用戶頁面的代碼和數據包。CSRF是代替用戶完成指定的動做,須要知道其餘用戶頁面的代碼和數據包。要完成一次CSRF攻擊,受害者必須依次完成兩個步驟

  • 登陸受信任網站A,並在本地生成Cookie

  • 在不登出A的狀況下,訪問危險網站B

CSRF的防護

  • 服務端的CSRF方式方法不少樣,但總的思想都是一致的,就是在客戶端頁面增長僞隨機數
  • 經過驗證碼的方法

2一、用過哪些設計模式?

  • 工廠模式:

    • 工廠模式解決了重複實例化的問題,但還有一個問題,那就是識別問題,由於根本沒法
    • 主要好處就是能夠消除對象間的耦合,經過使用工程方法而不是new關鍵字
  • 構造函數模式

    • 使用構造函數的方法,即解決了重複實例化的問題,又解決了對象識別的問題,該模式與工廠模式的不一樣之處在於
    • 直接將屬性和方法賦值給 this對象;

2二、爲何要有同源限制?

  • 同源策略指的是:協議,域名,端口相同,同源策略是一種安全協議
  • 舉例說明:好比一個黑客程序,他利用Iframe把真正的銀行登陸頁面嵌到他的頁面上,當你使用真實的用戶名,密碼登陸時,他的頁面就能夠經過Javascript讀取到你的表單中input中的內容,這樣用戶名,密碼就輕鬆到手了。

2三、offsetWidth/offsetHeight,clientWidth/clientHeight與scrollWidth/scrollHeight的區別

  • offsetWidth/offsetHeight返回值包含content + padding + border,效果與e.getBoundingClientRect()相同
  • clientWidth/clientHeight返回值只包含content + padding,若是有滾動條,也不包含滾動條
  • scrollWidth/scrollHeight返回值包含content + padding + 溢出內容的尺寸

2四、javascript有哪些方法定義對象

  • 對象字面量: var obj = {};
  • 構造函數: var obj = new Object();
  • Object.create(): var obj = Object.create(Object.prototype);

2五、常見兼容性問題?

  • png24位的圖片在iE6瀏覽器上出現背景,解決方案是作成PNG8
  • 瀏覽器默認的marginpadding不一樣。解決方案是加一個全局的*{margin:0;padding:0;}來統一,,可是全局效率很低,通常是以下這樣解決:
body,ul,li,ol,dl,dt,dd,form,input,h1,h2,h3,h4,h5,h6,p{
margin:0;
padding:0;
}
複製代碼
  • IE下,event對象有x,y屬性,可是沒有pageX,pageY屬性
  • Firefox下,event對象有pageX,pageY屬性,可是沒有x,y屬性.

2六、介紹js的基本數據類型

  • UndefinedNullBooleanNumberString

2七、介紹js有哪些內置對象?

  • ObjectJavaScript 中全部對象的父對象
  • 數據封裝類對象:ObjectArrayBooleanNumberString
  • 其餘對象:FunctionArgumentsMathDateRegExpError

2八、說幾條寫JavaScript的基本規範?

  • 不要在同一行聲明多個變量
  • 請使用===/!==來比較true/false或者數值
  • 使用對象字面量替代new Array這種形式
  • 不要使用全局函數
  • Switch語句必須帶有default分支
  • If語句必須使用大括號
  • for-in循環中的變量 應該使用var關鍵字明確限定做用域,從而避免做用域污

2九、JavaScript有幾種類型的值?,你能畫一下他們的內存圖嗎?

  • 棧:原始數據類型(UndefinedNullBooleanNumber、String
  • 堆:引用數據類型(對象、數組和函數)
  • 兩種類型的區別是:存儲位置不一樣;
  • 原始數據類型直接存儲在棧(stack)中的簡單數據段,佔據空間小、大小固定,屬於被頻繁使用數據,因此放入棧中存儲;
  • 引用數據類型存儲在堆(heap)中的對象,佔據空間大、大小不固定,若是存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其
  • 在棧中的地址,取得地址後從堆中得到實體
image

30、javascript建立對象的幾種方式?

javascript建立對象簡單的說,無非就是使用內置對象或各類自定義對象,固然還能夠用JSON;但寫法有不少種,也能混合使用

  • 對象字面量的方式
person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
複製代碼
  • function來模擬無參的構造函數
function Person(){}
    var person=new Person();//定義一個function,若是使用new"實例化",該function能夠看做是一個Class
        person.name="Mark";
        person.age="25";
        person.work=function(){
        alert(person.name+" hello...");
    }
person.work();
複製代碼
  • function來模擬參構造函數來實現(用this關鍵字定義構造的上下文屬性)
function Pet(name,age,hobby){
       this.name=name;//this做用域:當前對象
       this.age=age;
       this.hobby=hobby;
       this.eat=function(){
          alert("我叫"+this.name+",我喜歡"+this.hobby+",是個程序員");
       }
    }
    var maidou =new Pet("麥兜",25,"coding");//實例化、建立對象
    maidou.eat();//調用eat方法
複製代碼
  • 用工廠方式來建立(內置對象)
var wcDog =new Object();
     wcDog.name="旺財";
     wcDog.age=3;
     wcDog.work=function(){
       alert("我是"+wcDog.name+",汪汪汪......");
     }
     wcDog.work();
複製代碼
  • 用原型方式來建立
function Dog(){

     }
     Dog.prototype.name="旺財";
     Dog.prototype.eat=function(){
     alert(this.name+"是個吃貨");
     }
     var wangcai =new Dog();
     wangcai.eat();

複製代碼
  • 用混合方式來建立
function Car(name,price){
      this.name=name;
      this.price=price; 
    }
     Car.prototype.sell=function(){
       alert("我是"+this.name+",我如今賣"+this.price+"萬元");
      }
    var camry =new Car("凱美瑞",27);
    camry.sell(); 
複製代碼

3一、eval是作什麼的?

  • 它的功能是把對應的字符串解析成JS代碼並運行
  • 應該避免使用eval,不安全,很是耗性能(2次,一次解析成js語句,一次執行)
  • JSON字符串轉換爲JSON對象的時候能夠用eval,var obj =eval('('+ str +')')

3二、null,undefined 的區別?

  • undefined 表示不存在這個值。

  • undefined :是一個表示"無"的原始值或者說表示"缺乏值",就是此處應該有一個值,可是尚未定義。當嘗試讀取時會返回 undefined

  • 例如變量被聲明瞭,但沒有賦值時,就等於undefined

  • null 表示一個對象被定義了,值爲「空值」

  • null : 是一個對象(空對象, 沒有任何屬性和方法)

  • 例如做爲函數的參數,表示該函數的參數不是對象;

  • 在驗證null時,必定要使用 === ,由於 ==沒法分別null 和 undefined

3三、["1", "2", "3"].map(parseInt) 答案是多少?

  • [1, NaN, NaN]由於 parseInt 須要兩個參數 (val, radix),其中radix 表示解析時用的基數。
  • map傳了 3(element, index, array),對應的 radix 不合法致使解析失敗。

3四、javascript 代碼中的"use strict";是什麼意思 ? 使用它區別是什麼?

  • use strict是一種ECMAscript 5 添加的(嚴格)運行模式,這種模式使得 Javascript 在更嚴格的條件下運行,使JS編碼更加規範化的模式,消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲

3五、JSON 的瞭解?

  • JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式

  • 它是基於JavaScript的一個子集。數據格式簡單, 易於讀寫, 佔用帶寬小

  • JSON字符串轉換爲JSON對象:

var obj =eval('('+ str +')');
var obj = str.parseJSON();
var obj = JSON.parse(str);
複製代碼
  • JSON對象轉換爲JSON字符串:
var last=obj.toJSONString();
var last=JSON.stringify(obj);
複製代碼

3六、js延遲加載的方式有哪些?

  • deferasync、動態建立DOM方式(用得最多)、按需異步載入js

3七、同步和異步的區別?

  • 同步:瀏覽器訪問服務器請求,用戶看獲得頁面刷新,從新發請求,等請求完,頁面刷新,新內容出現,用戶看到新內容,進行下一步操做
  • 異步:瀏覽器訪問服務器請求,用戶正常操做,瀏覽器後端進行請求。等請求完,頁面不刷新,新內容也會出現,用戶看到新內容

3八、漸進加強和優雅降級

  • 漸進加強 :針對低版本瀏覽器進行構建頁面,保證最基本的功能,而後再針對高級瀏覽器進行效果、交互等改進和追加功能達到更好的用戶體驗。

  • 優雅降級 :一開始就構建完整的功能,而後再針對低版本瀏覽器進行兼容

3九、defer和async

  • defer並行加載js文件,會按照頁面上script標籤的順序執行
  • async並行加載js文件,下載完成當即執行,不會按照頁面上script標籤的順序執行

40、說說嚴格模式的限制

  • 變量必須聲明後再使用
  • 函數的參數不能有同名屬性,不然報錯
  • 不能使用with語句
  • 禁止this指向全局對象

4一、attribute和property的區別是什麼?

  • attributedom元素在文檔中做爲html標籤擁有的屬性;
  • property就是dom元素在js中做爲對象擁有的屬性。
  • 對於html的標準屬性來講,attributeproperty是同步的,是會自動更新的
  • 可是對於自定義的屬性來講,他們是不一樣步的

4二、談談你對ES6的理解

  • 新增模板字符串(爲JavaScript提供了簡單的字符串插值功能)
  • 箭頭函數
  • for-of(用來遍歷數據—例如數組中的值。)
  • arguments對象可被不定參數和默認參數完美代替。
  • ES6將3Promise對象歸入規範,提供了原生的Promise對象。
  • 增長了letconst命令,用來聲明變量。
  • 增長了塊級做用域。
  • let命令實際上就增長了塊級做用域。
  • 還有就是引入module模塊的概念

4三、ECMAScript6 怎麼寫class麼,爲何會出現class這種東西?

  • 這個語法糖可讓有OOP基礎的人更快上手js,至少是一個官方的實現了
  • 但對熟悉js的人來講,這個東西沒啥大影響;一個Object.creat()搞定繼承,比class簡潔清晰的多

4四、什麼是面向對象編程及面向過程編程,它們的異同和優缺點

  • 面向過程就是分析出解決問題所須要的步驟,而後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就能夠了
  • 面向對象是把構成問題事務分解成各個對象,創建對象的目的不是爲了完成一個步驟,而是爲了描敘某個事物在整個解決問題的步驟中的行爲
  • 面向對象是以功能來劃分問題,而不是步驟

4五、面向對象編程思想

  • 基本思想是使用對象,類,繼承,封裝等基本概念來進行程序設計
  • 優勢
    • 易維護
      • 採用面向對象思想設計的結構,可讀性高,因爲繼承的存在,即便改變需求,那麼維護也只是在局部模塊,因此維護起來是很是方便和較低成本的
    • 易擴展
    • 開發工做的重用性、繼承性高,下降重複工做量。
    • 縮短了開發週期

4六、對web標準、可用性、可訪問性的理解

  • 可用性(Usability):產品是否容易上手,用戶可否完成任務,效率如何,以及這過程當中用戶的主觀感覺可好,是從用戶的角度來看產品的質量。可用性好意味着產品質量高,是企業的核心競爭力
  • 可訪問性(Accessibility):Web內容對於殘障用戶的可閱讀和可理解性
  • 可維護性(Maintainability):通常包含兩個層次,一是當系統出現問題時,快速定位並解決問題的成本,成本低則可維護性好。二是代碼是否容易被人理解,是否容易修改和加強功能。

4七、如何經過JS判斷一個數組?

  • instanceof方法
    • instanceof 運算符是用來測試一個對象是否在其原型鏈原型構造函數的屬性
var arr = []; 
arr instanceof Array; // true
複製代碼
  • constructor方法
    • constructor屬性返回對建立此對象的數組函數的引用,就是返回對象相對應的構造函數
var arr = []; 
arr.constructor == Array; //true
複製代碼
  • 最簡單的方法
    • 這種寫法,是 jQuery 正在使用的
Object.prototype.toString.call(value) == '[object Array]'
// 利用這個方法,能夠寫一個返回數據類型的方法
var isType = function (obj) {
     return Object.prototype.toString.call(obj).slice(8,-1); 
}
複製代碼
  • ES5新增方法isArray()
var a = new Array(123);
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
複製代碼

4八、談一談let與var的區別?

  • let命令不存在變量提高,若是在let前使用,會致使報錯
  • 若是塊區中存在letconst命令,就會造成封閉做用域
  • 不容許重複聲明,所以,不能在函數內部從新聲明參數

4九、map與forEach的區別?

  • forEach方法,是最基本的方法,就是遍歷與循環,默認有3個傳參:分別是遍歷的數組內容item、數組索引index、和當前遍歷數組Array
  • map方法,基本用法與forEach一致,可是不一樣的,它會返回一個新的數組,因此在callback須要有return值,若是沒有,會返回undefined

50、談一談你理解的函數式編程?

  • 簡單說,"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論
  • 它具備如下特性:閉包和高階函數、惰性計算、遞歸、函數是"第一等公民"、只用"表達式"

5一、談一談箭頭函數與普通函數的區別?

  • 函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象
  • 不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤
  • 不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用Rest參數代替
  • 不可使用yield命令,所以箭頭函數不能用做Generator函數

5二、談一談函數中this的指向吧?

  • this的指向在函數定義的時候是肯定不了的,只有函數執行的時候才能肯定this到底指向誰,實際上this的最終指向的是那個調用它的對象

  • 《javascript語言精髓》中大概歸納了4種調用方式:

  • 方法調用模式

  • 函數調用模式

  • 構造器調用模式

graph LR
A-->B
複製代碼
  • apply/call調用模式

5三、異步編程的實現方式?

  • 回調函數

    • 優勢:簡單、容易理解
    • 缺點:不利於維護,代碼耦合高
  • 事件監聽(採用時間驅動模式,取決於某個事件是否發生):

    • 優勢:容易理解,能夠綁定多個事件,每一個事件能夠指定多個回調函數
    • 缺點:事件驅動型,流程不夠清晰
  • 發佈/訂閱(觀察者模式)

    • 相似於事件監聽,可是能夠經過‘消息中心’,瞭解如今有多少發佈者,多少訂閱者
  • Promise對象

    • 優勢:能夠利用then方法,進行鏈式寫法;能夠書寫錯誤時的回調函數;
    • 缺點:編寫和理解,相對比較難
  • Generator函數

    • 優勢:函數體內外的數據交換、錯誤處理機制
    • 缺點:流程管理不方便
  • async函數

    • 優勢:內置執行器、更好的語義、更廣的適用性、返回的是Promise、結構清晰。
    • 缺點:錯誤處理機制

5四、對原生Javascript瞭解程度

  • 數據類型、運算、對象、Function、繼承、閉包、做用域、原型鏈、事件、RegExpJSONAjaxDOMBOM、內存泄漏、跨域、異步裝載、模板引擎、前端MVC、路由、模塊化、CanvasECMAScript

5五、Js動畫與CSS動畫區別及相應實現

  • CSS3的動畫的優勢
    • 在性能上會稍微好一些,瀏覽器會對CSS3的動畫作一些優化
    • 代碼相對簡單
  • 缺點
    • 在動畫控制上不夠靈活
    • 兼容性很差
  • JavaScript的動畫正好彌補了這兩個缺點,控制能力很強,能夠單幀的控制、變換,同時寫得好徹底能夠兼容IE6,而且功能強大。對於一些複雜控制的動畫,使用javascript會比較靠譜。而在實現一些小的交互動效的時候,就多考慮考慮CSS

5六、JS 數組和對象的遍歷方式,以及幾種方式的比較

一般咱們會用循環的方式來遍歷數組。可是循環是 致使js 性能問題的緣由之一。通常咱們會採用下幾種方式來進行數組的遍歷

  • for in循環

  • for循環

  • forEach

    • 這裏的 forEach回調中兩個參數分別爲 valueindex
    • forEach 沒法遍歷對象
    • IE不支持該方法;Firefoxchrome 支持
    • forEach 沒法使用 breakcontinue 跳出循環,且使用 return 是跳過本次循環
  • 這兩種方法應該很是常見且使用很頻繁。但實際上,這兩種方法都存在性能問題

  • 在方式一中,for-in須要分析出array的每一個屬性,這個操做性能開銷很大。用在 key 已知的數組上是很是不划算的。因此儘可能不要用for-in,除非你不清楚要處理哪些屬性,例如 JSON對象這樣的狀況

  • 在方式2中,循環每進行一次,就要檢查一下數組長度。讀取屬性(數組長度)要比讀局部變量慢,尤爲是當 array 裏存放的都是 DOM 元素,由於每次讀取都會掃描一遍頁面上的選擇器相關元素,速度會大大下降

相關文章
相關標籤/搜索