首頁  >  文章  >  web前端  >  Javascript繼承(上)-物件建構介紹_JavaScript

Javascript繼承(上)-物件建構介紹_JavaScript

WBOY
WBOY原創
2016-05-16 17:48:361223瀏覽

Javascript中存在「類別」麼?

萬物皆物件
Javascript中除了基本資料(Undefined、Null、Boolean、Number、String),其他都是物件(Object)。
實際上,Javascript中的物件是資料與功能的集合。例如我們知道:

複製程式碼 程式碼如下:

var foo = new Function("alert ('hello world!')");
foo();

可見foo是個函數,也是一種物件。再比如說:
複製程式碼 程式碼如下:

{ //do something
}

foo.data = 123;
foo["data2"] = "hello";

alert(foo.data);
alert(foo.data2);

函數也可以像物件一樣加入屬性。

物件的建構 一般我們用建構子來建構對象,但如果沒有建構函數,我們也有辦法建構我們想要的物件:

複製程式碼 程式碼如下:
function creatPerson(__name, __sex, __age){
return {
freturn { sex: __sex,
age: __age,
get: function(__key){
alert(this[__key]);
}
};
}
}
}
}; >
var Bob = creatPerson("Bob", "male", 18);
Bob.get("name"); //Bob
Bob.get("sex"); //male
Bob.get("age"); //18


但這不夠,我希望方法是可以共享的。例如我再用該函數創建一個Tom對象,get函數就又被創建了一次,這明顯地浪費了我的記憶體。 導入共享資源

因為我們知道函數也是對象,所以我們可以把需要共享的方法或屬性放在他「身上」: 程式碼如下:


function creatPerson(__name, __sex, __age){
var commoncal = guments. ;
return {
//自身的屬性
name: __name,
sex: __sex,
age: __age,
//自身的方法
sayhi: function( ){alert("hi");},
//共享的方法
get: common.get,
getType: common.getType,
//共享的屬性
type: common.type
};
}
creatPerson.common = {
get:function(__key){
alert(this[__key]);
},
getType : function(){
alert(this.type);
},
type: "Person"
};

var Bob = creatPerson("Bob", "male ", 18);
Bob.get("name"); //Bob
Bob.get("sex"); //male
Bob.getType(); //Person


於是我們就用蹩腳的方法,成功的創建了一個擁有自有屬性方法和共享屬性方法的物件。但實際上,Javascript就是這麼蹩腳地創造物件的。
其實共享屬性沒有真正​​實現,因為這個共享屬性,依然只是副本。這並不是我們真正希望的共享屬性。
new關鍵字

和上面的「物件的建構」相同,new的目的是建立物件的自有屬性和方法。例如: 程式碼如下:


function Person(name, __sex,__name, __age)
this.name = __name;
this.sex = __sex;
this.age = __age;
this.get = function(__key){
alert(this[__key]);
};
}

var Bob = new Person("Bob", "male", 18);
Bob.get("name"); //Bob
Bob.get("sex"); //male
Bob.get("age"); //18

原型(Prototype)

Javascript的作者用了和上面「導入共享資源」的方法差不多。既然函數也是對象,那麼把需要分享的「東東」放在他「身上」吧: 程式碼如下:


function Person(__name, __sex, __age){
this.name = __name;
this.sex = __sex;
this.age = __age;
this.sayhi = function(__key){
alert("hi");
};
}
Person.prototype = {
constructor: Person,
get: function( __key){
alert(this[__key]);
}
};

var Bob = new Person("Bob", "male", 18);
Bob .get("name"); //Bob
Bob.get("sex"); //male
alert(Bob.constructor); //function Person


Javascript創建物件的模型是簡潔的,new來處理自身問題,prototype來處理共享問題。

如果說Java的物件(實例)產生方式是將原料丟到模子裡(類)熔煉而成;那麼Javascript的物件產生方式就是給材料給建築工(構造函數)讓他按圖紙搭建而成。

實際流程

當然實際流程並不是這樣的,新建一個物件先做的是處理共享資源,例如:
複製程式碼 程式碼如下:

function A(){
console.dir(this);
alert(this .type); //A
}
A.prototype.type = "A";
var a = new A();



透過console.dir將a印出來我們可以看到:
type "A"
__proto__ A {type = "A"}
  type "A"
  constructor A()

建構函式新建一個物件以後,立刻將其prototype的引用賦給新建物件的內部屬性__proto__,然後再執行建構函式裡面的建構語句。

並沒有覆蓋
複製程式碼 程式碼如下:
this.type = "B"
}
A.prototype.type = "A";

var a = new A();
alert(a. type); //B

當我們想要得到a.type時,引擎會先去在a物件中查看是否有屬性type,如果有則傳回該屬性,沒有則試圖在__proto_ _中尋找是否有type屬性,如果有則傳回該屬性。

__proto__並不是標準的,例如IE上沒有,但IE上也有類似的內部屬性,但我們也無法使用它。

基於這個原因,我們刪除a.type時依然可以回傳a.type:

複製程式碼複製程式碼

程式碼如下:


function A(){
this.type = "B"
}
A.prototype.type = "A";

var a = new A();
alert(a.type); //B
delete a.type;
alert(a.type); //A

到底有沒有類?


嚴格地講,Javascript並沒有類別(class)這種東西。
但有時我們會用構造函數的名字作為利用該構造函數創建的對象們的“類型(type not class)名”,以方便我們用Javascript進行面向對象編程時的交流。 名字只是一個代號,一個方便理解的工具罷了。

參考文獻
Javascript繼承機制的設計思想
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn