javascript物件導向(2)--原型鏈及屬性介紹

私有屬性

var Person = function (){
    var name;
};

 

 

公有屬性

var Person = function (){
    this.name;
};

get,set範例

var Person = function(){
    var _name;
    this.setName = function(name){
         _name = name;
    };
    this.getName = function(){
         return _name;
    };
};

利用prototype在在外部宣告屬性

var Person = function(){
    var _name = "null";
    this.setName = function(name){
         _name = name;
    };
    this.getName = function(){
            return name;
    };
};
    
Person.prototype.age = 0;
Person.prototype.getAge = function(){
    return this.age;
};
Person.prototype.setAge = function(age){
    this.age = age;
};

或者使用{}

var Person = function(){
    var _name = "null";
    this.setName = function(name){
         _name = name;
    };
    this.getName = function(){
         return name;
    };
};
 
Person.prototype = {
    age : 0,
    getAge :function(){
        return this.age;
    },
    setAge :function(age){
        this.age = age;
    }
};

原型鍊初步介紹

實際上我們可以將屬性age放在function裡面,程式一樣能夠照常運行。那如果我們將age同時放在function,prototype裡,那們程式會讀到哪個age呢?

答案是function,範例如下:

var Person = function(){
    this.age = 100;
};
 
Person.prototype = {
    age : 0,
    getAge :function(){
       return this.age;
    },
    setAge :function(age){
       this.age = age;
    }
};

var person = new Person();
person.getAge();//得到 100 

為什麼為這樣呢?那就不得不說說原型鍊的概念了。再建立function時,每一個function都會預設一個prototype值,當我們宣告this.age時,依照此例,此處的this是Person,因此會先從Person裡面尋找是否存在age的屬性,如果找不到age的資料,他會開始從prototype裡面尋找有沒有age的屬性,如果依舊沒有就繼續尋找下一個prototype,到prototype的值為null為止。

容易混淆的觀念

剛剛提到每一個function都有一個prototype,因此如果我們多次使用prototype繼承(用new的方式),他會造成後面繼承的function取代前面繼承前面的function,如下例Father取代了Mother

var Mother = function(){
    this.mClass = "Mother";
    this.name = "瑪力蘇";
};

var Father = function(){
    this.fClass = "Father";
    this.name = "龍傲天";
};

var Children = function(){
    this.name = "傲世無雙";
};

Children.prototype = new Mother();
Children.prototype = new Father();

var children = new Children();
log(children.name);    //return 傲世無雙
log(children.mClass);  //return undenfined prototype以經被取代了
log(children.fClass);  //return Father

但如果不使用(new)的方式,我們是可以多次使用protopyte的,不用擔心被取代的問題。

//宣告資料
var Father = function(){
    this.fClass = "Father";
    this.name = "龍傲天";
};

var Children = function(){};
Children.prototype.name = "傲世無雙";
Children.prototype.age = 20;

var children = new Children();
log(children.name); //return 傲世無雙
log(children.age);  //return 20

var children = new Children();

log(children.fClass);//return Father  最開始的fClass依然存在
log(children.name); //return 傲世無雙     讀到後面的資料
log(children.age);  //return 20   讀到後面的資料

為什麼把new放在前後面會有這種差異呢?

原因是這樣的,prototype會指向某個objcet,請注意new Function產生的就是object物件,當我們直接宣告屬性時,程式所做的事就將這個object添加一個屬性,而使用new的時候,則是將prototype指向另外一個新產生的object,所以原本所設的屬性,就通通不見了。

最後在作一個提醒,還記得一開始我們將prototype指向一個{}嗎?實際上他也是用new宣告一個新的物件。

Person.prototype = {  
    getName: function() {  
        return this.name;  
    }  
}; 

//上面等於下面
Person.prototype = new Object({  
    getName: function() {  
        return this.name;  
    }  
});

 

 

 

 

 


因為很多文章是過往自己搜集的資料、圖片,如有侵權疑慮請告知,將立即下架刪除。