您的位置:首页 > Web前端 > JavaScript

JavaScript面向对象

2009-09-18 10:40 260 查看

面向对象目标

我假设读者对JavaScript有基本的了解,包括事件回调,并且了解面向对象编程。
我认为面向对象编程的三个主要的目标是:
² 封装 提供一个方法,去调用JavaScript对象里边的成员
² 多态 两个类响应同样一个方法
² 继承 定义一个类的子类

通过以下例子,我将演示如下技术:


定义一个类


定义类里边的回调方法


定义一个子类


从子类调用基类的构造函数


在子类中重写基类的方法


在子类中调用基类的方法

简单对象

在JavaScript中,最简单的对象就是构建一个Object的数据类型。在JavaScript中,可以把一组命名后的属性集合放在一块儿执行。作为一种解释型语言,JavaScript允许你在任何地方任何时间去创建属性。
下面,我们举一个例子,首先创建一个对象,然后添加多个属性给这个对象:
obj = new Object;
obj.x = 1;
obj.y = 2;
我用如下的图形表示JavaScript对象:

obj
x
1
y
2
Object.prototype
constructor
Object
其中,左列显示的是对象的每个可用的属性,右列显示的值。在这个里边,其实我们定义了一个JavaScript内置的构造函数,包含两个属性。在后边,我会解释prototype这个属性的。

定义一个类

一个方法可以很容易定义出一个JavaScript类。下面的代码片段定义了一个类 foo,然后,创建了这个类的对象。
function Foo()
{
this.x = 1;
this.y = 2;
}

obj = new Foo;

obj
x
1
y
2
Foo.prototype
constructor
Foo
Object.prototype
(constructor)
Object
只要你愿意,你可以创建很多个Foo类型的对象,它们分别会初始化各自的属性,将x 与 y赋值为1和2.

解释prototypes

在JavaScript中,每一个对象都可以从其它的对象进行继承,我们称之为prototype。当执行到某属性时,JavaScript会首先直接从该对象中寻找是否具有,如果没有,那么就在对象的object prototype中寻找该属性,像一条锁链一样,一直追溯到根原型(root prototype).

例如,我们希望创建一个对象object,X来自于方法B,B的原型是B.prototype, A.prototype, Object.prototype:

我们可以用下面的代码表示:
Object.prototype.inObj = 1;

function A()
{
this.inA = 2;
}

A.prototype.inAProto = 3;

B.prototype = new A; // Hook up A into B's prototype chain
B.prototype.constructor = B;
function B()
{
this.inB = 4;
}

B.prototype.inBProto = 5;

x = new B;
document.write(x.inObj + ', ' + x.inA + ', ' + x.inAProto + ', ' + x.inB + ', ' + x.inBProto);
1, 2, 3, 4, 5

x
inB
4
B.prototype
constructor
B
inA
2
inBProto
5
A.prototype
(constructor)
A
inAProto
3
Object.prototype
(constructor)
Object
inObj
1

定义并且调用类的方法

function Foo()
{
this.x = 1;
}

Foo.prototype.AddX = function(y) // Define Method
{
this.x += y;
}

obj = new Foo;

obj.AddX(5); // Call Method

obj
x
6
Foo.prototype
constructor
Foo
AddX
function ...
Object.prototype
(constructor)
Object
多态
function A()
{
this.x = 1;
}

A.prototype.DoIt = function() // Define Method
{
this.x += 1;
}

function B()
{
this.x = 1;
}

B.prototype.DoIt = function() // Define Method
{
this.x += 2;
}

a = new A;
b = new B;

a.DoIt();
b.DoIt();
document.write(a.x + ', ' + b.x);
2, 3

a
x
2
A.prototype
constructor
A
DoIt
function ...
Object.prototype
(constructor)
Object
b
x
3
B.prototype
constructor
B
DoIt
function ...
Object.prototype
(constructor)
Object

定义一个子类

function A() // Define super class
{
this.x = 1;
}

A.prototype.DoIt = function() // Define Method
{
this.x += 1;
}

B.prototype = new A; // Define sub-class
B.prototype.constructor = B;
function B()
{
A.call(this); // Call super-class constructor (if desired)
this.y = 2;
}

B.prototype.DoIt = function() // Define Method
{
A.prototype.DoIt.call(this); // Call super-class method (if desired)
this.y += 1;
}

b = new B;

document.write((b instanceof A) + ', ' + (b instanceof B) + '
');
b.DoIt();
document.write(b.x + ', ' + b.y);

true, true
2, 3

b
x
2
y
3
B.prototype
constructor
B
(x)
1
DoIt
function ...
A.prototype
(constructor)
A
(DoIt)
function ...
Object.prototype
(constructor)
Object

An Alternate Sub-Classing Paradigm

Function.prototype.DeriveFrom = function(fnSuper)
{
var prop
if (this == fnSuper)
{
alert("Error - cannot derive from self");
return;
}
for (prop in fnSuper.prototype)
{
if (typeof(fnSuper.prototype[prop]) == "function" && !this.prototype[prop])
{
this.prototype[prop] = fnSuper.prototype[prop];
}
}

this.prototype[fnSuper.StName()] = fnSuper;
}
Function.prototype.StName = function()
{
var st;
st = this.toString();
st = st.substring(st.indexOf(" ")+1, st.indexOf("("));
if (st.charAt(0) == "(")
st = "function ...";
return st;
}
Function.prototype.Override = function(fnSuper, stMethod)
{
this.prototype[fnSuper.StName() + "_" + stMethod] = fnSuper.prototype[stMethod];
}
Repeating the sub-classing example using this new paradigm:
function A() // Define super class
{
this.x = 1;
}

A.prototype.DoIt = function() // Define Method
{
this.x += 1;
}

B.DeriveFrom(A); // Define sub-class
function B()
{
this.A(); // Call super-class constructor (if desired)
this.y = 2;
}

B.Override(A, 'DoIt');
B.prototype.DoIt = function() // Define Method
{
this.A_DoIt(); // Call super-class method (if desired)
this.y += 1;
}

b = new B;

document.write((b instanceof A) + ', ' + (b instanceof B) + '
');
b.DoIt();
document.write(b.x + ', ' + b.y);

false, true
2, 3

b
x
2
y
3
B.prototype
constructor
B
DoIt
function ...
A
A
A_DoIt
function ...
Object.prototype
(constructor)
Object

私有成员

令人吃惊的是,JavaScript支持对象的私有成员。
function A()
{
var x = 7;

this.GetX = function() { return x;}
this.SetX = function(xT) { x = xT; }
}

obj = new A;
obj2 = new A;
document.write(obj.GetX() + ' ' + obj2.GetX());
obj.SetX(14);
document.write(' ' + obj.GetX() + ' ' + obj2.GetX());
7 7 14 7

obj
GetX
function ...
SetX
function ...
A.prototype
constructor
A
Object.prototype
(constructor)
Object
obj2
GetX
function ...
SetX
function ...
A.prototype
constructor
A
Object.prototype
(constructor)
Object
Trackback: http://mckoss.com/jscript/object.htm

JavaScript面向对象编程(1)-- 基础
/article/5398581.html

JavaScript面向对象编程(2)-- 类的定义
/article/5398583.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: