jQuery1.0源代碼分析之方法繼承(三) – Javascript教程_JS教程_技術文章 – 程式設計聯盟

 

上一篇,我們介紹瞭jQuery是如何new出來的jQuery對象,這一篇講解jQuery方法是如何繼承的。

 

 

在分析jQuery的方法繼承前,我們先來弄清楚javascript的原型繼承。看下面一段代碼:

 

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "https://www.w3.org/TR/html4/strict.dtd"> 

<html lang="en"> 

<head> 

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 

    <title></title> 

    <script type="text/javascript"> 

    // Person類 

    function Person(name) { 

        this.name = name; 

    } 

     

    // 原型方法 

    Person.prototype.sayHello = function() { 

        Person.sayHello(this); 

    } 

     

    // 靜態方法 

    Person.sayHello = function(p) { 

        alert(p.name + ', hello !'); 

    } 

     

    // Person實例對象 

    var tom = new Person('Tom'); 

    tom.sayHello(); 

 

    </script> 

</head> 

<body> 

</body> 

</html> 

上面的代碼很簡單,創建瞭一個Person類,給Person添加方法有兩種途徑,第一種是把方法註冊在Person.prototype上,這裡叫做原型方法,第二種是把方法註冊在Person上,叫做靜態方法。

靜態方法很簡單,就相當於java裡的static method,在內存中隻有一份,並且它的函數內部this是指向Person的。

 

原型方法就相當於類的方法,我們首先new瞭一個Person對象叫tom,當我們調用tom.sayHello(),瀏覽器會首先查明tom是什麼類,也就是瀏覽器會去查找tom的constructor屬性,這個屬性代表著實例的構造函數。tom的constructor是指向Person的,那也就是說tom是Person類的實例。然後瀏覽器會查看Person的prototype屬性上有沒有sayHello方法,有則調用之。

 

Person.prototype默認就是new Object()對象,所以你調用alert(tom.toString())會彈出[ object Object ],那是因為調用瞭Object的toString方法,因為Person.prototype沒有覆蓋toString方法啊。

 

再有就是prototype還可以等於其他類,例如Person.prototype = new Animal(),這樣tom在調用sayHello方法的時候,當找到Person.prototype屬性時發現是Animal,瀏覽器會繼續向上追溯,查找Animal.prototype屬性上有沒有sayHello方法,沒有則繼續向上查一直到Object的prototype屬性。這樣就實現瞭類的繼承,這樣的繼承也叫原型繼承。

 

再來看看jQuery的extend方法,1.0的版本中這個方法很簡單,就是對象屬性的淺拷貝。代碼如下:

 

 

jQuery.extend = jQuery.fn.extend = function(obj,prop) { 

    if ( !prop ) { prop = obj; obj = this; } 

    for ( var i in prop ) obj[i] = prop[i]; 

    return obj; 

}; 

 

傳一個參數時,會把obj的屬性復制到this上,傳兩個參數時,會把prop的屬性復制到obj上。

 

現在,再來看看jQuery的方法繼承,我挑瞭一個很常用的each方法,是不是一下就能看清楚啊。

 

 

function jQuery(a,c) { 

 

    if ( window == this ) 

        return new jQuery(a,c); 

 

 

jQuery.fn = jQuery.prototype = { 

 

    each: function( fn, args ) { 

             return jQuery.each( this, fn, args ); 

    }, 

 

}; 

 

jQuery.extend({ 

 

    each: function( obj, fn, args ) { 

        if ( obj.length == undefined ) 

            for ( var i in obj ) 

                fn.apply( obj[i], args || [i, obj[i]] ); 

        else 

            for ( var i = 0; i < obj.length; i++ ) 

                fn.apply( obj[i], args || [i, obj[i]] ); 

        return obj; 

    }, 

 

}); 

jQuery對象調用原型方法,原型方法調用靜態方法,調用時把this作為參數傳進去,靜態方法返回時要把this返回。這樣就實現瞭jQuery的方法鏈

 

作者 baozhifei

發佈留言