JavaScript 是一種物件導向的程式語言,但確不存在類別的概念,這跟我們以往在 Java、C++、C# 等語言上所學到的物件導向觀念有很大的不同,也是一般JavaScript 初學者所要適應與轉變的觀念。談 OOP 總離不開封裝、繼承與多型等基本觀念,而 JavaScript 在實作這三者時與Java、C++、C# 等語言也有著截然不同的作法,唯有先搞清楚 JavaScript 中原型式的物件導向觀念與作法,才能在使用 JavaScript 這門語言時游刃有餘。首先我們將透過如何在 js 中建立物件的幾種方式來展開 JavaScript  OOP 之旅

 

   JavaScript 中要建立一個物件,非常簡單,不像Java、C++、C# 等語言要透過  Class 才有辦法建立一個物件

第一種方法是透過所謂的實字符號模式(literal notation patterns) ,快速的建立一個物件,如下程式片段:

var dog = {};     //空物件

dog.name = “harry”;

dog.getName = function(){

     return dog.name;

};

也可以這樣建立一個新物件:

var dog = {

     name: “harry”,

     getName: function(){

          return this.name;   //or return name

}

};

當我們只想為物件建立一個執行個體時,會使用此方式,此方式不適合於需建立多個相同物件模板的運用

 

第二種方式是透過內建的建構式(constructor functions)來建立一個新的物件:

var dog = new Object();//空物件,但會自動從 Object.prototype 承屬性與方法

console.log(dog.constructor === Object)’ //true

dog.name = “harry”;

此種方式也只適用於想為物件建立一個執行個體時使用

 

另外需注意的是: Object 可以接受一個參數,此時傳回的就不一定是 Object 如下例:

var obj = new Object(1);

console.log(o.constructor === Number); //true

var obj = new Object(“harry”);

console.log(o.constructor === String); //true

var obj = new Object(true”);

console.log(o.constructor === Boolean); //true

 所以在使用上時要別別小心,尤其是在動態建立物件的情況下,可能很容易得到不如預期的結果。

 

第三種方法是透過自訂建構式函式來建立新物件,透過這種方式建立物件,JavScript 引擎會在背後做一些事,如下例:

var Dog = function(name){

     //使用物件實字自動建立一個空物件

     // var this = Object.create(Dog.prototype);

     this.name = name;

     this.getName = function(){

          return this.name;

};

// return this;  //隱式傳回 this 物件

};

 

var dog = new Dog(“harry”);  //雖然很像 Java與 c# 中透過類別建立物件的方式,但它並不是,它稱為函式建構子

dog.getName; //harry

 

這種建立物件的方式有一個缺點,就是你每建立一個新的物件,就會有一個新的屬性及方法被建立在記憶體中,對於物件的屬性來說是合理,因為每個物件的屬性值本來就會有所不同,但對於可重覆利用的方法來說,很明顯這是一種記憶體上的浪費,應該透過如下的程式片段來達成方法的共用:

var Dog = function(name){

     this.name = name;    

};

Dog.prototype.getName = function(){

     return this.name;

};

這樣當透過自訂建構式函式建立二個以上的物件時,實際上只會在記憶體建立一份方法:

var dog1 = new Dog(“harry”);

dog1.getName; //harray

var dog2 = new Dog(“marry”);

dog2.getName; // marry

 

自訂建構式函式時,也可以透如下的方式定義屬性和方法

var Dog = function({   

};

Dog.name = “harray”;

Dog.getName = function(){

     return this.name;

};

但需注意的是,透過這種方式宣告的屬性與方法稱為靜態屬性與方法,有如下的特性:

console.log(Dog.name); //harry
console.log(typeof Dog. getName); //function
           
var o=new Dog ();
console.log(o.name); //undefined

console.log(typeof o. getName); //undefined

 

另外,關於自訂建構式函式需要注意的是,一定要使用 new 來建立物件,如果忘了使用 new  在建構式中的 this 就會指向全域物件,也就是在瀏覽器中, this 就指向 window

var dog = Dog();

console.log(typeof dog); // undefined 忘了new, 不會有物件this回傳, 變成全域

console.log(window.name); //全域變數

可以透過下列的技巧讓自訂建構式函式無諭使用那一種方式,一定會回傳物件:

 

在上面三種建立物件的方法時,有二個  keyword 出現,一個是 prototype 及 constructor,下一篇文章,我們將介紹這二個 keyword 讓我們向 JavaScript 式的 OOP 更接近一步

文章標籤
全站熱搜
創作者介紹
創作者 thomas0728 的頭像
thomas0728

Y湯哥的自言自語

thomas0728 發表在 痞客邦 留言(4) 人氣(2,368)