前端面試題(八)

  • 瀏覽器內多個標籤頁之間的通訊方式有哪些

    這個問題沒有進行過多的研究, 借閱一下別人的答案 網頁消息通訊
    1. WebSocket (可跨域)
      WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
    2. postMessage(可跨域)
      window.postMessage()方法安全地啓用Window對象之間的跨源通訊git

      對將接收消息的窗口的引用,得到此類引用的方法包括:github

      1. iframe標籤
      2. Window.open (生成一個新窗口而後引用它)
      3. Window.opener (引用產生這個的窗口)
    3. Worker之SharedWorker
      做爲瀏覽器的一個新特性,能夠提供一個額外的線程來執行一些js代碼(真正的多線程),而且不會影響到瀏覽器用戶界面,可是不能DOM操做。web

      SharedWorker能夠被多個window共同使用,因此能夠用來跨頁面傳輸數據,但必須保證這些標籤頁都是同源的(相同的協議,主機和端口號)
    4. Server-Sent Events
      HTML5 服務器發送事件(server-sent event)容許網頁得到來自服務器的更新。Server-Sent 事件指的是網頁自動獲取來自服務器的更新。之前也可能作到這一點,前提是網頁不得不詢問是否有可用的更新。經過服務器發送事件,更新可以自動到達
    5. localStorage
      localstorage是瀏覽器多個標籤共用的存儲空間,因此能夠用來實現多標籤之間的通訊(ps:session是會話級的存儲空間,每一個標籤頁都是單獨的)。 直接在window對象上添加監聽便可。
    6. BroadcastChannel
      這個方式,只要是在同一原始域和用戶代理下,全部窗口、iframe之間均可以進行交互。這個感受就有點相似於廣播了。
    7. Cookies
      Cookies在同一個域名內,而且目錄也得相同

  • 簡述你理解的優雅降級和逐漸加強

    優雅降級:面試

    先不考慮兼容,優先最新版本瀏覽器效果,以後再逐漸兼容低版本瀏覽器

    逐漸加強:json

    考慮兼容,以較低(多)瀏覽器效果爲主,以後再逐漸增長對新版本瀏覽器的支持,之內容爲主。也是多數公司所採用的方法。

  • 寫一個判斷數據類型的方法

    通常來講有這麼幾種辦法, 可是有着各自的一些缺陷
    1. typeof
    若是使用 typeof 來判斷數據類型的話:跨域

    console.log(
        typeof 123, //"number"
        typeof 'dsfsf', //"string"
        typeof false, //"boolean"
        typeof [1,2,3], //"object"
        typeof {a:1,b:2,c:3}, //"object"
        typeof function(){console.log('aaa');}, //"function"
        typeof undefined, //"undefined"
        typeof null, //"object"
        typeof new Date(), //"object"
        typeof /^[a-zA-Z]{5,20}$/, //"object"
        typeof new Error() //"object"
    );

    經過上面的測試發現:瀏覽器

    Array,Object,null,Date,RegExp,Error這幾個類型都被typeof判斷爲object,因此若是想要判斷這幾種類型,就不能使用typeof了。
    Number,String,Boolean,Function,undefined,若是想判斷這幾種類型,那就可使用typeof

    2. instanceof
    instanceof運算符須要指定一個構造函數,或者說指定一個特定的類型,它用來判斷這個構造函數的原型是否在給定對象的原型鏈上。安全

    console.log(
        123 instanceof Number, //false
        'dsfsf' instanceof String, //false
        false instanceof Boolean, //false
        [1,2,3] instanceof Array, //true
        {a:1,b:2,c:3} instanceof Object, //true
        function(){console.log('aaa');} instanceof Function, //true
        undefined instanceof Object, //false
        null instanceof Object, //false
        new Date() instanceof Date, //true
        /^[a-zA-Z]{5,20}$/ instanceof RegExp, //true
        new Error() instanceof Error //true
    )

    能夠發現:服務器

    Number,String,Boolean沒有檢測出他們的類型,可是若是使用下面的寫法則能夠檢測出來:
    var num = new Number(123);
    var str = new String('dsfsf');
    var boolean = new Boolean(false);
    還須要注意null和undefined都返回了false,這是由於它們的類型就是本身自己,並非Object建立出來它們,因此返回了false。

    3. constructor
    constructor是prototype對象上的屬性,指向構造函數。根據實例對象尋找屬性的順序,若實例對象上沒有實例屬性或方法時,就去原型鏈上尋找,所以,實例對象也是能使用constructor屬性的.
    若是輸出一個類型的實例的constructor,就以下所示:session

    console.log(new Number(123).constructor)
    //ƒ Number() { [native code] }

    能夠看到它指向了Number的構造函數,所以,可使用num.constructor==Number來判斷一個變量是否是Number類型的。

    var num  = 123;
    var str  = 'abcdef';
    var bool = true;
    var arr  = [1, 2, 3, 4];
    var json = {name:'wenzi', age:25};
    var func = function(){ console.log('this is function'); }
    var und  = undefined;
    var nul  = null;
    var date = new Date();
    var reg  = /^[a-zA-Z]{5,20}$/;
    var error= new Error();
    
    function Person(){
    
    }
    var tom = new Person();
    
    // undefined和null沒有constructor屬性
    console.log(
        tom.constructor==Person,
        num.constructor==Number,
        str.constructor==String,
        bool.constructor==Boolean,
        arr.constructor==Array,
        json.constructor==Object,
        func.constructor==Function,
        date.constructor==Date,
        reg.constructor==RegExp,
        error.constructor==Error
    );
    //全部結果均爲true
    除了undefined和null以外,其餘類型均可以經過constructor屬性來判斷類型。

    4. 使用toString()檢測對象類型
    能夠經過toString() 來獲取每一個對象的類型。爲了每一個對象都能經過 Object.prototype.toString() 來檢測,須要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式來調用,傳遞要檢查的對象做爲第一個參數,稱爲thisArg。

    var toString = Object.prototype.toString;
    
    toString.call(123); //"[object Number]"
    toString.call('abcdef'); //"[object String]"
    toString.call(true); //"[object Boolean]"
    toString.call([1, 2, 3, 4]); //"[object Array]"
    toString.call({name:'wenzi', age:25}); //"[object Object]"
    toString.call(function(){ console.log('this is function'); }); //"[object Function]"
    toString.call(undefined); //"[object Undefined]"
    toString.call(null); //"[object Null]"
    toString.call(new Date()); //"[object Date]"
    toString.call(/^[a-zA-Z]{5,20}$/); //"[object RegExp]"
    toString.call(new Error()); //"[object Error]"
    這樣能夠看到使用Object.prototype.toString.call()的方式來判斷一個變量的類型是最準確的方法。

    綜上所述
    封裝一個獲取變量準確類型的函數:

    function gettype(obj) {
      var type = typeof obj;
    
      if (type !== 'object') {
        return type;
      }
      //若是不是object類型的數據,直接用typeof就能判斷出來
    
      //若是是object類型數據,準確判斷類型必須使用Object.prototype.toString.call(obj)的方式才能判斷
      return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
    }

    這樣判斷一個變量的數據類型就很方便了。

面試題摘自Github

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息