基于javascript的面向对象的实现
一 类的定义
1.静态属性和方法
js并没有静态作用域,不过它可以给构造函数提供属性和方法:
function sayHi(){ alert("hi"); } sayHi.alternate = function(){ alert("hoal"); } sayHi();//outputs "hi"
2. 关键字this
它用在对象的方法中,总是指向调用该方法的对象.
注意:引用对象的属性时,必须使用this关键字
var oCar = new Object; oCar.color = "red"; oCar.showColor = function(){ alert(this.color); }
3.工厂模式
function showColor(){ alert(this.color); } function createCar(sColor,iDoors,iMpg) { var oTempCar = new Object; oTempCar.color = sColor; oTempCar.doors = iDoors; oTempCar.mpg = iMpg; oTempCar.showColor = showColor; return oTempCar; } var oCar1 = createCar("red",4,23); var oCar2 = createCar("green",3,25); oCar1.showColor(); oCar2.showColor();
4.构造函数
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.showColor = function (){ alert(this.color); } } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.showColor(); oCar2.showColor();
在构造函数内部无创建对象,而是使用this关键字.使用new运算符调用构造函数时,在执
行第一行代码前先创建一个对象,只有用this才能访问该对象.然后可以直接赋予this属性
.默认情况下是构造函数的返回值(不必明确使用return运算符)
5.混合的构造函数/原型方式
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; } Car.prototype.showColor = function (){ alert(this.color); } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.showColor(); oCar2.showColor();
构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)
alert(oCar1 instanceof Car);
instantceof oCar1是否是Car的一个对象..
6.动态原型方法
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; if (typeof Car._initialized == "undefined"){ Car.prototype.showColor = function (){ alert(this.color); } } Car._initialized = true; } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.showColor(); oCar2.showColor();
7.字符串的连接建议使用Array对象
var arr = new Array(); arr[0] = "hello"; arr[1] = "world"; var str = arr.join(""); alert(str); 设计StringBuffer类打包该功能: function StringBuffer(){ this.__strings__ = new Array; } StringBuffer.prototype.append = function(str){ this.__strings__.push(str); } StringBuffer.prototype.toString = function(){ return this.__strings__.join(""); } var buffer = new StringBuffer(); buffer.append("hello "); buffer.append("world"); var result = buffer.toString();
可能节省100%~200%的时间
8.创建新方法
如果想结每个本地对象添加新方法,必须在Object对象的prototype属性上定义它,因为每
个对象都是继承了Object对象,所有驿Object对象做任何改变,都会瓜在所有本地对象中.
.
Object.prototype.showValue = function(){ alert(this.valueOf()); } var str = "hqlong"; var iNum = 24; str.showValue(); iNum.showValue();
9.重定义已有方法
function.prototype.toString = function(){ return "Function code hidden"; }
toString指针被无用存储单元回收程序回收,这样原函数将完全被废弃,所以在存储原函数
之前,最好存储它的指针,这样会比较安全.
function.prototype.originalToString = Function.prototype.toString;
10.极晚绑定
对象实例化以后定义对象的方法.
var o = new Object; Object.prototype.sayHi = function(){ alert("hi"); }
不建议使用极晚绑定方法,因为很难对其进行跟踪和记录..
二 继承机制
1.对象冒充
function ClassA(sColor){ this.color = sColor; this.sayColor = function(){ alert(this.color); } } function ClassB(sColor,sName){ this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod; this.name = sName; this.sayName = function(){ alert(this.name); } } var objA = new ClassA("red"); var objB = new ClassB("blue","Nicholas"); objA.sayColor(); objB.sayColor(); objB.sayName();
2.call()方法
它的第一个参数用作this的对象,其他参数直接一地一的传给函数自身.
function ClassA(sColor){ this.color = sColor; this.sayColor = function(){ alert(this.color); } } function ClassB(sColor,sName){ ClassA.call(this,sColor); this.name = sName; this.sayName = function(){ alert(this.name); } } var objA = new ClassA("red"); var objB = new ClassB("blue","Nicholas"); objA.sayColor(); objB.sayColor(); objB.sayName();
3.apply()方法
用作this的对象和要传递给函数的参数的数组
function ClassA(sColor){ this.color = sColor; this.sayColor = function(){ alert(this.color); } } function ClassB(sColor,sName){ ClassA.call(this,new Array(sColor)); this.name = sName; this.sayName = function(){ alert(this.name); } } var objA = new ClassA("red"); var objB = new ClassB("blue","Nicholas"); objA.sayColor(); objB.sayColor(); objB.sayName();
如果超类中的参数顺序和中的参数顺序完全一致,可以使用arguments对象作为第二个参数
传递给apply
方法.
4.原型链:
这种方式是基于对象原型的,prototype对象是个模板,要实例化的对象都以这个模板为基
础,prototype对象的任何属性和方法都被传递给那个类的所有实例.原型链利用这种功能
来实现继承机制.
function ClassA(){} ClassA.prototype.color = "red"; ClassA.prototype.sayColor = function(){ alert(this.color); } function ClassB(){} ClassB.prototype = new ClassA();
这里,把ClassB的属性设置成ClassA的实例.这里很有意思,因为想要ClassA的所有属性和
方法,但又不想逐个将它们赋予ClassB和prototype属性.恐怕没有比这更好的方法了.
Notice:调用ClassA的构造函数时,没有给它传递参数.这里在原型链中是标准做法.要确
保构造函数没有任何参数.
子类的所有属性和方法都必须出现在prototype属性被赋值后,因为在它之前的所有赋值都
会被删除.
5.混合方法:
主要是在原型链在基础上使用构造函数
function ClassA(sColor){ this.color = sColor; } ClassA.prototype.sayColor = function(){ alert(this.color); } function ClassB(sColor,sName){ ClassA.call(this,sColor); } ClassB.prototype = new ClassA(); ClassB.prototype.sayName = function(){ alert(this.name); };
机器人 2008年2月28日 于 整理于 北京
参考资料: http://book.csdn.net/bookfiles/110/1001103139.shtml