初步学习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>