/*
匈牙利类型标记法
在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,如下所示“
var iMyTestValue = 0, sMySecondValue = "hi";
本教程采用了这些前缀,以使示例代码更易阅读:
类型 前缀 示例
数组 a aValues
布尔型 b bFound
浮点型 f fValue
函数 fn fnMethod
整型(数字) i iValue
对象 o oType
正则表达式 re rePattern
字符串 s sValue
变型(可以是任何类型) v vValue
var sName="";声明一个字符串变量 S代表变量类型
*/
/***********************创建类*****************************************************
混合的构造函数/原型方式
联合使用构造函数和原型方式,就可像用其他程序设计语言一样创建对象。这种概念非常简单,即用构造函数定义对象的所有非函数属性,
用原型方式定义对象的函数属性(方法)。结果是,所有函数都只创建一次,而每个对象都具有自己的对象属性实例。
我们重写了前面的例子,代码如下:*/
/*******************《类定义一》****************
*
*这种写法是吧所以的都写在一起
*好处达到了类的完全封装
*缺点是 没创建一个实例时 都会从复创建fn_num1和fn_num2函数
*
*/
var TestObject=function(){
//private params
var param1='this is param_1';
var param2='this is param_2';
//public params
this.param3='this is param_3';
this.param4='this is param_4';
//private functions
function fn_num1(){ //浪费内存 即每次创建该TestObject类实例时都会给该函数(fn_num1)分配内存
alert('here is fn_num1');
};
//public functions
this.fn_num2=function(){
fn_num1(); //没错
alert(param1);//没错
}
};
var oTestObject=new TestObject();
oTestObject.fn_num2();
/*******************《类定义二》****************/
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
}
Car.prototype.showColor = function() {
alert(color); //报错 相当于局部变量 所以必需用this
alert(this.color);
};
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //输出 "Mike,John,Bill"
alert(oCar2.drivers); //输出 "Mike,John"
/*个人总结 这种方式没有浪费内存,因为采用原型方式来创建类,即该类的所以实例都指向同一个函数对象(函数也是一个对象),从功能上讲,这样解决了重复创建函数对象的问题
*缺点和不足 这种写法不能在公用方法内调用私有方法和属性 如下:
*/
/*******************《类定义三》*****不提倡这种里外都写,因为他们是相互独立的还浪费内存***********/
var TestObject=function(){
//private params
var param1='this is param_1';
var param2='this is param_2';
//public params
this.param3='this is param_3';
this.param4='this is param_4';
//private functions
function fn_num1(){ //浪费内存 即每次创建该TestObject类实例时都会给该函数(fn_num1)分配内存 并且只能访问 param1m,param2m不能访问param3和param4 因为它属于TestObject函数类而不属于任何实例
alert('here is fn_num1');
};
};
TestObject.prototype.fn_num2=function(){ //节约内存 即每次创建TestObject类实例时变量fn_num2都指向同一个函数(fn_num1)不会从复分配内存
fn_num1(); //报错
alert(param1);//报错
};
function Car(sColor,iDoors,iMpg) {
//this.color = sColor;
this.doors = 'sdfsdfsd';
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
var num='abc';// 这种写法和 Car._initialized 一个意思 也就所以实例公用该变量 所以不能乱使用这个
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function() {
alert(num);
test();
num='dddddddddd';
};
//Car的方法 相等于private 避免了 从复分配 但它访问不到 成员变量 如 this.doors = 'sdfsdfsd';this.mpg = iMpg; this.drivers ,因为它是属于Car函数类,二不属于实例
//所以这种函数没有什么意义
function test(){
alert('this is test');
alert(this.doors);// underfine
alert(num);
this.showColor();//报错
showColor();//报错
}
Car._initialized = true;
}
}
var ndd=new Car();
ndd.showColor();
输出:/>'abc'
/>'this is test'
var nddss=new Car();
nddss.showColor();
输出:/>'dddddddddd'
/>'this is test'
/************************《类定义四》******************************************/
function Car(sColor,iDoors,iMpg) {
//this.color = sColor;
this.doors = 'this is test';
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
var num=0; //属于Car 函数类,即所以实例共享一个变量,相当于 java的static 变量
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function() {
alert(this.doors);
alert(num);
num++;
};
Car._initialized = true;
}
}
var ndd=new Car();
ndd.showColor();
输出:/>'this is test'
/>0
var nddss=new Car();
nddss.showColor();
输出:/>'this is test'
/>1
/*
*
*最后总结:一般情况下提倡使用《类定义二》即变量写在构造器里,方法写在‘类’外面,并且一个js里只写一个类(为了好区分)
*当需要很多局部吧变量时可以考虑使用《类定义一》,因为也是完全可以用《类定义二》,
只是在外面可以操作变量而已程序元在写程序是注意一下心里明白它是(比如认为是局部变量就可以了如 我们定义这种变量时使用this._SparamName;或this._SparamName_;,一下划线表示)就可以了
*
/**************************创建类 实例 结束*******************************************************/
/*************************扩展Object类 就像扩展JQuery 的插件一样*********************************
为本地对象添加新方法
最后,如果想给 ECMAScript 中每个本地对象添加新方法,必须在 Object 对象的 prototype 属性上定义它。前面的章节我们讲过,
所有本地对象都继承了 Object 对象,所以对 Object 对象做任何改变,都会反应在所有本地对象上。例如,如果想添加一个用警告输出对象的当前值的方法,可以采用下面的代码:
*/
Object.prototype.showValue = function () {
alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue(); //输出 "hello"
iNum.showValue(); //输出 "25"
/*TIY
这里,String 和 Number 对象都从 Object 对象继承了 showValue() 方法,分别在它们的对象上调用该方法,将显示 "hello" 和 "25"。
**************************扩展Object类 实例结束 ***********************************************/