JavaScript中,每個function都擁有一個原型對象prototype,通過這個對象可以為這個類定義各種屬性和方法,但是這樣定義的屬性和方法是所有該類的對象所共有的,效果上和同這個類的父類中繼承的字段和方法差不多。通常我們使用function的原型來創建類的方法,而用普通方式來創建類的屬性。
1.為什么不用原型來創建屬性
因為原型創建的內容是這個類所有對象所共享的,對於一個屬性而言,不同的類的對象的值都不一樣。如果使用原型對象來創建對象屬性,那么任何一個類的對象修改了自己的某個屬性,其他對象的相同屬性也會被修改。
這么做的本質是因為:屬性是各個對象不同的,要求對象自己保存自己該屬性的值,而方法對於所有對象而言都是一樣的,沒有必要每個對象都保存一個方法,只要由類的原型保存一份,各個對象使用方法的時候調用這些方法就可以了。
2.為什么要用原型來保存方法
因為方法對所有類對象來說都是一樣的,如果用傳統方式定義,那樣每個類的對象被定義的時候,該對象都會保存這個方法的信息,這樣會耗
費很多資源。而使用原型來保存,所有的方法都保存在原型中,每個對象需要使用方法的時候就調用原型對象中保存的方法。節省了資源。
在類中定義共享的共有方法,私有靜態屬性和方法,共有靜態屬性和方法。
//一種更為合適的公用屬性和方法的定義,把共有方法在類第一次調用的時候加到類的原型對象中
var Book = function(name){
//公有屬性,在構造方法里面來定義,通過this關鍵字
this.name = name;
//第一次執行該對象的構造方法,這個時候執行下面的代碼
//為類的原型對象上定義共有的方法
//所有該類的對象共享相同的共有對象,減小了內存的消耗
if (typeof Book._init == "undefined") {//在第一次定義該類對象的時候會成立
//共有的方法,在原型對象上定義
Book.prototype.setName = function(nname) {
this.name = nname;
};
Book.prototype.getName = function(){
return this.name;
};
Book.prototype.getCount = function(){
addCount();
return count;
};
}
//類已經被定義過了,以后就不再重新定義原型對象上的方法了
Book._init = true;
//利用局部變量來模擬私有靜態屬性和方法
//這些局部變量定義出來的方法和屬性外界不能直接訪問,只能通過公有方法訪問,
var count = 0;
var addCount = function(){
count++;
}
};
//定義共有靜態屬性
Book.staticValue = 10;
//定義共有的靜態方法
Book.changeValue = function() {
Book.staticValue++;
}
對上面類的調用方法
//這個new操作相當於先創建了一個簡單對象,調用了類的構造方法
var book1 = new Book("AJAX");
var book2 = new Book("AJAX1");
alert(book1.getName());
alert(book2.getName());
book1.setName("JAVA");
alert(book1.getName());
alert(book2.getName());
alert(book1.getCount());
alert(book2.getCount());
alert(book1.getCount());
//共有的靜態屬性和方法要用類名來調用
alert(Book.staticValue);
Book.changeValue();
alert(Book.staticValue);
定義一個對象,希望這個對象擁有一些自己獨享的私有信息
方法:直接定義一個匿名的類
//一個單獨的對象,期望擁有一些私有有的信息
下面的方法和上面的起到一樣的效果,
//利用匿名方法直接調用的方式,來實現一個對象擁有私有的信息
var priObj = (function(name){
//由於這個變量是在方法內定義的,起到的效果就是私有的
var priname = name;
//這個格式要求返回的是一個對象,
//這個對象要求有getName和setName兩個方法
return {
getName:function() {
return priname;
},
setName:function(nname) {
priname = nname;
}
};
})("wang");
下面是上面對象的使用方法
//var priObj1=new priObj("a");
//var priObj2=new priObj("b");
上面的做法是錯誤的,因為這個priObj已經是個定義好的對象了,在定義匿名類的同時就定義好的,所以不能再這么去new了。
//priObj.priname是私有內容,無法訪問
alert(priObj.priname);
alert(priObj.getName());
priObj.setName("Lee");
alert(priObj.getName());
alert("");
1.為什么不用原型來創建屬性
因為原型創建的內容是這個類所有對象所共享的,對於一個屬性而言,不同的類的對象的值都不一樣。如果使用原型對象來創建對象屬性,那么任何一個類的對象修改了自己的某個屬性,其他對象的相同屬性也會被修改。
這么做的本質是因為:屬性是各個對象不同的,要求對象自己保存自己該屬性的值,而方法對於所有對象而言都是一樣的,沒有必要每個對象都保存一個方法,只要由類的原型保存一份,各個對象使用方法的時候調用這些方法就可以了。
2.為什么要用原型來保存方法
因為方法對所有類對象來說都是一樣的,如果用傳統方式定義,那樣每個類的對象被定義的時候,該對象都會保存這個方法的信息,這樣會耗
費很多資源。而使用原型來保存,所有的方法都保存在原型中,每個對象需要使用方法的時候就調用原型對象中保存的方法。節省了資源。
在類中定義共享的共有方法,私有靜態屬性和方法,共有靜態屬性和方法。
//一種更為合適的公用屬性和方法的定義,把共有方法在類第一次調用的時候加到類的原型對象中
var Book = function(name){
//公有屬性,在構造方法里面來定義,通過this關鍵字
this.name = name;
//第一次執行該對象的構造方法,這個時候執行下面的代碼
//為類的原型對象上定義共有的方法
//所有該類的對象共享相同的共有對象,減小了內存的消耗
if (typeof Book._init == "undefined") {//在第一次定義該類對象的時候會成立
//共有的方法,在原型對象上定義
Book.prototype.setName = function(nname) {
this.name = nname;
};
Book.prototype.getName = function(){
return this.name;
};
Book.prototype.getCount = function(){
addCount();
return count;
};
}
//類已經被定義過了,以后就不再重新定義原型對象上的方法了
Book._init = true;
//利用局部變量來模擬私有靜態屬性和方法
//這些局部變量定義出來的方法和屬性外界不能直接訪問,只能通過公有方法訪問,
var count = 0;
var addCount = function(){
count++;
}
};
//定義共有靜態屬性
Book.staticValue = 10;
//定義共有的靜態方法
Book.changeValue = function() {
Book.staticValue++;
}
對上面類的調用方法
//這個new操作相當於先創建了一個簡單對象,調用了類的構造方法
var book1 = new Book("AJAX");
var book2 = new Book("AJAX1");
alert(book1.getName());
alert(book2.getName());
book1.setName("JAVA");
alert(book1.getName());
alert(book2.getName());
alert(book1.getCount());
alert(book2.getCount());
alert(book1.getCount());
//共有的靜態屬性和方法要用類名來調用
alert(Book.staticValue);
Book.changeValue();
alert(Book.staticValue);
定義一個對象,希望這個對象擁有一些自己獨享的私有信息
方法:直接定義一個匿名的類
//一個單獨的對象,期望擁有一些私有有的信息
下面的方法和上面的起到一樣的效果,
//利用匿名方法直接調用的方式,來實現一個對象擁有私有的信息
var priObj = (function(name){
//由於這個變量是在方法內定義的,起到的效果就是私有的
var priname = name;
//這個格式要求返回的是一個對象,
//這個對象要求有getName和setName兩個方法
return {
getName:function() {
return priname;
},
setName:function(nname) {
priname = nname;
}
};
})("wang");
下面是上面對象的使用方法
//var priObj1=new priObj("a");
//var priObj2=new priObj("b");
上面的做法是錯誤的,因為這個priObj已經是個定義好的對象了,在定義匿名類的同時就定義好的,所以不能再這么去new了。
//priObj.priname是私有內容,無法訪問
alert(priObj.priname);
alert(priObj.getName());
priObj.setName("Lee");
alert(priObj.getName());
alert("");