初步學習JS的面向對象特性,部分內容來自互聯網,感謝原作者,並對其進行了擴充,以下代碼在VS2010+IE9中調試通過:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
//構造函數
function myContructor(message) {
//公有屬性
this.myMessage = message;
//私有屬性
var separator ='-';
var myOwner = this;
//私有方法
function alertMessage() {
alert(myOwner.myMessage);
}
alertMessage();
//特權方法
this.appendToMessage = function (string) {
this.myMessage += separator + string;
alertMessage();
}
return this;
};
//原型定義的公有方法
myContructor.prototype.clearMessage = function (string) {
this.myMessage = 'clear!';
}
//靜態屬性
myContructor.prototype.name2 = '';
//靜態屬性
myContructor.name = 'Jankerli';
//靜態方法
myContructor.alertName = function () {
alert("類方法:"+this.name);
}
function fun()
{
var obj = myContructor("qzf");
//(1)對象方法
alert("外部調用的公用屬性:" + obj.myMessage); //能訪問;構造中調用的私有方法
obj.appendToMessage("new"); //構造函數中定義的特權方法
alert("對象外部訪問內部私有屬性:"+obj.myOwner); //提示未定義
//obj.alertMessage(); //私有方法,報錯提示不支持次方法;
//(2)類方法,類屬性
myContructor.name = "CBX"; //類的屬性(相當於C#的靜態屬性)
myContructor.alertName(); //類的方法(相當於C#靜態方法)
alert("用實例來訪問類的靜態成員:"+obj.name); //能訪問,用實例來訪問類的靜態成員的結果是空;
//obj.alertName(); //報錯,不能用實例來訪問類的靜態方法;
//(3)原型方法,使用原型等於指向一個類的單例對象
alert(obj.name2); //這個對象不是用原型的渠道創建的,原型屬性未定義
//obj.clearMessage("OK"); //報錯:這個對象不是用原型的渠道創建的,原型方法不讓用
//obj.prototype.clearMessage("OK"); //報錯:這個也不讓調用,類名後才能跟prototype;
myContructor.prototype.clearMessage("OK1"); //等於myContructor.prototype這是個匿名對象(其實用類名就可以找到它)
var protoObj = myContructor.prototype; //用變量抓下這個匿名對象,讓它有名
protoObj.clearMessage("OK"); //這個對象變量是用原型的渠道創建的,可以使用原型方法
protoObj.name2 = "-----"; //這個用原型的渠道創建的對象,也能使用原型定義的公有屬性
alert("原型渠道創建的對象能使用原型屬性:" + protoObj.name2);
alert("原型渠道創建的對象能使用原型方法:" + protoObj.myMessage); //用原型的渠道創建的對象,照樣能使用對象的公有屬性
//protoObj和obj理論上都是myContructor的實例化對象
//而protoObj.clearMessage可以,但obj.clearMessage不可以,要把obj氣死了,
//不過沒關係也有原型對象訪問不了的:
//protoObj.appendToMessage("NNew"); //這句報錯,用原型的渠道創建的對象,不能使用對象的特權方法!
var protoObj2 = myContructor.prototype; //讓用另一個變量也指向這個對象,myContructor.prototype被兩個對象引用了
protoObj2.myMessage = "ABCD";
alert("原型的單例對象在其它地方改了,一改所有以後引用的對象都改了,protoObj的屬性:" + protoObj.myMessage);
alert("原型的單例對象在其它地方改了,一改所有以後引用的對象都改了,類.prototype的屬性:" + myContructor.prototype.myMessage);
alert("非原型的渠道創建的對象不受影像:" + obj.myMessage);
//用傳統面向對象(以C#/Java爲例)角度看,myContructor是基類/父類;
//原型相當於擴展類/子類;
//但是擴展類只能是單例;
//與傳統面向對象不同的是:
//(與基類相當的)myContructor類的對象能訪問的公有方法,而(與子類地位相當的)原型對象卻不能訪問appendToMessage方法
//按照傳統面向對象的思路,子類不能基父類訪問的方法,那說明方法是私有的啊,
//但是JS中父類中這個方法不是私有的,因爲父類的對象能訪問,這是不同的地方
var cc = protoObj.prototype; //未定義
}
</script>
</head>
<body>
<input style="margin-top:10px" type="button" onclick="fun()" value="測試調用" />
</body>
</html>