JS面向對象編程--過程式分析

聲明:php

概念性介紹會簡單穿插,以過程式分析問題爲主,便於提升實踐的意義。

前言:java

面向對象,早已爛熟於耳,以java爲最,php5.6以後更是擴展了面向對象式開發(起先引入對象概念,沒當個大方向,這下無意插柳柳成蔭,繁盛起來了),js也基於對象式開發了。。。

開扒瀏覽器

可是,JS沒有類的概念,是構造函數和原型鏈的方式來體現的。

我這裏僅經過1個例子(有點懶~),儘可能全面的分析下實現過程。app

/*=================定義「類」=================*/
   /*=======父類Foo=======*/
   function Foo(name,age){
     this.name = name;    //this是當前 [調用FOO()構造函數的] 對象,若是有子類Bar繼承則表明子類對象
     this.age = age;      //this.參數名,則意味着各個對象,有屬於本身的名字和年齡
    }                     //如上,是對象間差別化、獨立性的體現
    
    /*父類Foo的原型*/
    Foo.prototype = {         //在此定義Foo對象公有的方法/屬性,以節省內存、便於維護(性能上:若是把sayHi()方法定義在了Foo(name,age)構造函數中,等於說每new一個Foo或子類對象,每一個對象在堆內存就會多佔點空間來存放sayHi()方法,耗內存啊。)   
        sayHi:function(){     //公有方法  
            alert("Hi,I'm "+this.name);
        },
        guess:888             //公有屬性
    };
    
    /*=======子類Bar=======*/
    function Bar(name,age,sex){    
        Foo.call(this,name,age); //等同於Foo.apply(this,[name,age]);你要初始化的東東,父類搞好了,只管調用
        this.sex = sex;          //Bar對象自己的特有屬性
    }  
    /*子類Bar的原型是個Foo對象*/
    Bar.prototype = new Foo();   //Bar的原型類=Foo對象,意味着Bar對象能調到自己沒有卻在(Foo對象或者Foo.prototype)中存在的屬性或方法
    
    //建立並調用
    var bar = new Bar('Lin',18,'male'); 
    bar.sayHi();

運行效果:函數

clipboard.png

案例補充說明:性能

1)var bar = new Bar('Lin',18,'male'); 
    解釋:
        new 一個 Bar對象,名爲bar.
        bar就繼承了Foo類的屬性和Foo原型上的方法。
        
    2)bar.sayHi();    //可調
    解釋:
        bar對象,首先自身查找是否有sayHi()方法,沒有則bar.__proto__獲得Bar.prototype;
        在Bar.prototype這個原型對象中繼續查找,而前面咱們已指定Bar.prototype = new Foo();
        則意味着是在Foo對象中查找,然而Foo對象自己沒有sayHi()方法;
        則調用(new Foo()).__proto__獲得原型對象Foo.prototype;
        繼續在該原型對象Foo.prototype中查找sayHi()方法;
        終於找到了!!!返回結果吧。
    
    擴展:
       若是依然沒找到,就會Foo.prototype.__proto__獲得Object.prototype,
       Object.prototype自己沒有sayHi()方法,就會
       Object.prototype.__proto__獲得null.
       null是最頂級的對象。在該對象中,查無此方法,就報錯了;查無此屬性,就undefined.

涉及術語:this

原型鏈
    各構造函數,各有與之相對應的原型;
    類之間的繼承,就暗暗的把原型間的關係統籌在了一塊兒。
    頂層原型上方法或屬性的查找過程,就是依靠着原型間的這種關係,一層一層的向上查找的。

原型繼承
     Bar.prototype = new Foo(); 

借用繼承
     Foo.call(this,name,age); //Foo.apply(this,[name,age]);

組合繼承
     function Bar(name,age,sex){    
        Foo.call(this,name,age);
        this.sex = sex;                
     }  
    Bar.prototype = new Foo();  

    現象式總結:        
        僅是原型繼承,子類Bar確實可調用(父類Foo的屬性和原型上的方法)了,但實例化出來的Bar對象就不獨立了。意味着某個對象對Foo構造函數中的屬性或方法的修改,會影響到其餘對象調用的結果.
        簡言之,子類可調父類了,可是實例化的對象不獨立。

        僅是借用繼承,子類bar實例化的對象是獨立的,對象間不受影響,但父類原型上的方法調不了了.
   
        推薦組合繼承,既保證了對象間的獨立性,又能調用到父類的原型上的方法。

福利:spa

1.原型鏈圖示(網上找的,看懂便可跳過上述內容)

clipboard.png
該圖把原型和構造函數間的關係理的很清楚,可在Google瀏覽器的console運行demo並查看對象下原型間的關係。prototype

2.JS高級部分,以前看的是ali的Bosn的JavaScript深刻淺出

若有不適內容,歡迎指正。code

相關文章
相關標籤/搜索