面試題延伸及總結

      從一開始記住某個特性的某類特色到要去深挖原理,我不得不說............恩恩,都是面試官逼個人呀!他們會問爲何會出現事件冒泡和事件捕獲兩種?angularJS的理念是什麼?new出來的對象和調用function有什麼區別。。。css

每次我下意識的反應都是:啊?面試

。。。。。。數組

而後在夜深人靜的時候默默的看書看博客去還原他們問的問題的答案。瀏覽器

並且我想說知識點真的是太多太雜了。。。因此我會常常性的以爲我簡直是弱爆了。。。。老是被活生生的摧殘。。已不想多說一句話。。。dom

相關比較大塊的東西,就總結在博客上ide

一、jQuery中怎麼判斷一個DOM樹加載完畢?

這個問題以前是看到過的,可是沒有深究,因此此次問到就答得亂七八糟。函數

平時用jQ會很順手的上來寫js就寫$(function(){...}) [$(document).ready()]。可是它是有別於winodw.onload的,它們的觸發時機是不一樣的this

winodw.onload:是等到頁面中所引用的img等全部的外部資源所有加載,而且在瀏覽器中顯示後才執行!spa

                       因此,若是有不少不少的img或者是img很大會致使onload執行推遲prototype

在JQ中,提供了domready,即$(function(){...}),它是在DOM樹加載完畢後就當即執行,而不須要整個文檔內容加載完成。

 

二、事件的過程是怎樣的?(其實就是問事件捕獲和事件冒泡啊!!)

簡述事件冒泡和事件捕獲的概念和發生的順序:

 

 

(以點擊事件爲例)

冒泡:事件會從最內層的元素開始發生,一直向上傳播,直到document對象

捕獲:事件會從最外層開始發生,一直傳播到被點擊元素上

「DOM2級事件」規定事件流包括了三個部分:事件捕獲階段、處於目標階段、事件冒泡階段。事件流同時支持了事件捕獲階段和事件冒泡階段

W3C規定,同時存在兩種事件流時,首先進入捕獲階段,直到到達目標元素再進入冒泡階段

addEventListener在IE8及如下的瀏覽器不兼容,可使用attachEvent替代,attachEvent僅有兩個參數,默認是冒泡模型。

如下圖爲例,詳細解釋這部份內容:

<div id="div1">div1
    <div id="div2">div2
        <div id="div3">div3
            <div id="div4">div4</div>
        </div>
    </div>
</div>
  1. 四個div所有設置爲冒泡,點擊div4——執行順序:4-->3-->2-->1
  2. 四個div所有設置爲捕獲,點擊div4——執行順序:1-->2-->3-->4
  3. 一、3設置爲冒泡,二、4設置爲捕獲,點擊4——執行順序:2-->4-->3-->1
  4. 下面咱們給div2既添加冒泡又設置捕獲:
        div1.addEventListener("click",function(){
            alert("div1");
        },false);
        div2.addEventListener("click",function(){
            alert("div2捕獲");
        },true);
        div2.addEventListener("click",function(){
            alert("div2冒泡");
        },false);

    點擊div2——執行順序:div2捕獲 --> div2冒泡 --> div1

        div1.addEventListener("click",function(){
            alert("div1");
        },false);
        div2.addEventListener("click",function(){
            alert("div2冒泡");
        },false);
        div2.addEventListener("click",function(){
            alert("div2捕獲");
        },true);

    點擊div2——執行順序:div2冒泡 --> div2捕獲 --> div1

     由上面兩段代碼和執行結果可得: 綁在點擊元素身上的事件會按照代碼的書寫順序執行!

  5. 仍是分別執行上面兩段代碼,若是如今不是點擊div2,而是點擊div3或div4——執行順序:div2捕獲 --> div2冒泡 --> div1。這裏就和書寫順序無關了,而是遵循W3C的規定,先執行捕獲再執行冒泡!

關於阻止冒泡:

ev.stopPropagation() 等價於 ev.cancelBubble = true

前者符合W3C標準,不支持IE

後者不符合W3C

還有一個相似於ev.stopPropagation()的:ev.stopImmediatePropagation()

ev.stopPropagation():不會影響當前節點的任何事件監聽器,會阻止事件流中當前節點後續的節點的事件

ev.stopImmediatePropagation():當即生效!當前節點也會被影響!

 

感受面試官特別喜歡問這個問題!而後有的加點難度的,除了讓你描述事件冒泡和事件捕獲實現方式,

還會問:爲何會出現這兩種過程?

這個問題。。。事件冒泡是微軟提出的,事件捕獲是網景提出的,二者沒有優劣之分,都是爲了解決事件流前後順序的問題。可是相比較而言,事件冒泡的兼容性更好一些。

還會問:何時不須要阻止冒泡?何時要利用冒泡呢?

<div class="box">點我隱藏
    <div class="button">click點我變色</div>
</div>
<script> $('.box').click(function(ev){ $('.box').hide(); }) $('.button').click(function(ev){ ev.stopPropagation(); // !!! $('.button').css('backgroundColor','blue') }) </script>

上面這個例子是這樣的:若是點擊.box但願整個.box隱藏,若是點擊.box內部的.button則讓.button變色。

此時,若是不加stopPropagation,那麼點擊.button後仍是會隱藏整個.box。由於事件冒泡傳遞到.box上,觸發了.box的點擊事件。

因此,必須阻止冒泡才能實現上述想要的效果。

 

三、instanceof

    function Person(name){
        this.name = name;
    }
    var person1 = new Person('ning');
    var person2 = [];
    alert(person1 instanceof Person)    // true
    alert(person2 instanceof Person)    // false

形如:obj instanceof class    obj是class的一個實例的時候返回true,不然返回false。

instanceof經過返回一個布爾值來指出這個對象是不是這個特定類或者是它子類的一個實例!

在js中如何判斷一個對象oStringObject是否爲String?

js中String的初始化有兩種方式:一、直接賦值,var str1 = 'abcd'

                                          二、String對象實例化,var str2  = new String('ac');

若是用第二種方式初始化,就不能用typeof來判斷,由於此時typeof是判斷基本數據類型的,null/[]/{}/對象/函數都屬於object

這時能夠用instanceof!

    var oStringObject = new String('aaa')
    alert(typeof oStringObject)   // object
    alert(oStringObject instanceof String)  // true
    alert(Object.prototype.toString.call(oStringObject)=='[object String]')   // true

後面兩種方式均可以來判斷oStringObject是否是String!

 

四、關於數組內置方法的返回值

 返回結果和註釋都在代碼中標明瞭!主要注意push/unshift的返回值是數組的長度!shift/pop的返回值是刪掉的那個元素值!splice的返回值也是刪掉的元素值!

    var str = 'abcdefg'
    //返回的就是截取的字符串
    console.log(str.substring(0,2))   // ab
    console.log(str.slice(0,2))   // ab

    // split返回的是一個數組
    console.log(str.split('b'))   // ['a','cdefg']
    console.log(str.split(''))    // ['a','b','c','d','e','f','g']

    var arr = ['aa','bb','cc']
    // join返回的是一個字符串
    console.log(arr.join())     //aa,bb,cc   (length=8)
    console.log(arr.join(''))   // aabbcc    (length=6)

    // push返回的是數組長度!!!push操做事後,arr就是push以後的新數組!!!
    console.log(arr.push(1))   // 4
    console.log(arr)           // ['aa','bb','cc',1]

    //unshift也是返回的是數組長度!!!
    console.log(arr.unshift('ning'))    // 5
    console.log(arr)                    // ['ning','aa','bb','cc',1]

    // pop返回的是刪掉的那個元素,也就是arr最後一位的那個元素
    console.log(arr.pop())    // 1
    console.log(arr)          // ['ning','aa','bb','cc']

    // shift返回的是刪掉的那個元素,也就是arr第一位的那個元素
    console.log(arr.shift())    // ning
    console.log(arr)          // ['aa','bb','cc']


    var arr2 = arr.splice(1,2,'new')
    console.log(arr)       // 返回splice操做以後的原來的數組
    console.log(arr2)      // 返回的是刪掉的那個元素!! 效果與console.log(arr.splice(1,2,'new')) 等價

 

五、零碎

  • if判斷內還有for循環內不容許寫函數聲明!!函數聲明就不能寫在運算中!可是if(function fn1(){...})會返回true,可是!!typepf fn1的結果是undefined
  • 下面這三個題~
    var str1 = 5 + 'nihao';
    var str2 = true + 'nihao';
    var str3 = 5 + true;
    console.log(typeof str1)  // string     '5nihao'
    console.log(typeof str2)  // string     'truenihao'
    console.log(typeof str3)  // number      5

關於null的一些容易混淆的:

    console.log(typeof null)  // object
    console.log(null instanceof Object)  //  false   null不是以Object爲原型建立出來的!
    console.log(null == undefined)  // true
    console.log(false == undefined)  // false
相關文章
相關標籤/搜索