无梦家园

无梦家园
posts - 21, comments - 150, trackbacks - 8, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

JavaScript的面向对象机理1)-类

Posted on 2007-02-04 08:42 沧桑雨迢迢 阅读(2214) 评论(12)  编辑 收藏 所属分类: Javascript
JavaScript中的"类",其实就是函数
   下面来简单来一个"类"的例子:
<script type="text/javascript">
//MyClass本质上就是一个函数,但可以当类来使用
function MyClass(name){
    
this.name = name;
}

var m = new MyClass("fanrong");
alert(m.name);
</script>
   这里成功定义和使用了一个自定义的JavaScript类:MyClass.
所谓类的实例化是如何实现的?
   在JavaScript中,"类"实例化一个对象,是依靠JavaScript可动态增加属性的特点来实现的,如下示例:
<script type="text/javascript">
var a = {};
a.name 
= "fanrong";
alert(a.name);
</script>
   当我们定义变量a时,还没有name属性,但是我们在接下来的一行代码中,"直接"对a.name进行了赋值(这一点相当重要,这是JavaScript的函数之所以能成为类的关键所在).
    然后再回到我们的MyClass类,它其实是一个函数,当你在new MyClass("fanrong")时,你做了两件事:1>你用new 关键字创建了一个object类型的对象,此时这个对象很干净,基本没有任何的属性.2>你开始调用MyClass方法了,而且是以(new Object()).MyClass("fanrong")这样的形式调用的,这样,MyClass函数体内的this指针就指向了新创建的对象,而this.name = name,其实就相当与本例的a.name = "fanrong"了,依靠的,还是JavaScript的"动态添加属性"的特点.
另一种类实现方式—Prototype原型对象
   好了,以上您已经了解了在JavaScript中怎么实现类的一种方法了,下面介绍另一种...不要急,JavaScript中一共也就2种实现类的方法,而下面这一种,更优秀且更通用,如prototype.js/aspnet ajax等库都是主要基于下面这一种prototype原型对象的方式来实现的.
   首先看例子:
<script type="text/javascript">
function MyClass(){    
}

MyClass.prototype.name 
= "fanrong";
var m = new MyClass();
alert(m.name);
</script>
   这里的重点在于MyClass的prototype属性.这是JavaScript的又一个特点,prototype属性是每个JavaScript对象都具备的,从它动态扩展的属性/方法等,能"自动"赋予被new的对象.因此,alert(m.name)会显示"fanrong",而不是undefined.
   prototype这个属性好象天生就是为了设计JavaScript的类而出现的...它的优点在于它是"自动"赋予被实例化对象的,这一点很重要.你可以看到,在本例的MyClass函数体内,没一行代码使变量m与name属性发生关系,但是name在MyClass实例化之后,使m具备了name属性.
   也许有人疑惑本例中由prototype定义的类属性好象不能初始化,而第一例就可以,其实不然.下面我来演示下:
<script type="text/javascript">
function MyClass(name){    
    alert(
this.name);
    
this.name = name;
}

MyClass.prototype.name 
= "haha";
var m = new MyClass("fanrong");
alert(m.name);
</script>
   在实例化时,首先会弹出一个对话框,显示this.name的值,这里会显示"haha".说明当进入到MyClass函数体内部时,this.name已经具备了(由prototype优先赋予了).而如果是第一个例子,而是"undefined",是还未定义的!这一点区别很重要.
如何区别类和实例对象
   这个其实很简单,如下:
<script type="text/javascript">
function MyClass(name){       
    
this.name = name;
}

MyClass.prototype.name 
= "haha";
var m = new MyClass("fanrong");

//区分类与实例对象
alert(typeof(MyClass));   //显示 function
alert(
typeof(m));               //显示 object
</script>
   ...类就是function,而实例对象就是object...
   简单吧~
如何判断对象是否是某一个类的实例
   这里的技巧是使用instanceof方法,如下:
<script type="text/javascript">
function A(){}
function B(){}
var m = new A();
alert(m 
instanceof(A));//true
alert(m instanceof(B));//false
</script>
   应该m是A的实例,所以显示true,而B则不是,所以显示false了.也还是比较简单的.
如何运用这两种类定义方法
   以我的看法,设计一个类时,在prototype上定义所有的属性和方法,而在函数体内进行初始化工作,如下示例:
<script type="text/javascript">
function MyClass(name){           
    
this._name = name;  //在函数体内初始化属性
}

MyClass.prototype 
= {      //在prototype上定义属性和方法
    _name: null,
    showName: 
function(){
        alert(
this._name);
    }

}

var m = new MyClass("fanrong");
m.showName();
</script>

   好了,到这里,基本已经讲JavaScript的"类"实现的两种方法了:一是依靠JavaScript的动态属性扩展能力,二是依靠JavaScript的prototype原型对象.
   

Feedback

#1楼    回复  引用  查看    

2007-02-04 09:10 by Jeffrey Zhao      
很好啊。感觉可以提一下intanceof操作符。:)

#2楼 [楼主]   回复  引用  查看    

2007-02-04 09:20 by 沧桑雨迢迢      
@Jeffrey Zhao
恩,加上去了,用来判断某个实例是否属于某个类~~~

#3楼    回复  引用  查看    

2007-02-04 09:22 by Jeffrey Zhao      
在这里就是用来区分new MyClass('fanrong')和{ name : 'fanrong' }。
虽然在使用上似乎一样,但是两者还是有区别的。:)

#4楼    回复  引用  查看    

2007-02-04 10:00 by 一滴水      
学习了!

#5楼    回复  引用    

2007-02-04 10:20 by net [未注册用户]
晕 js 渐行渐远

#6楼 [楼主]   回复  引用  查看    

2007-02-04 10:31 by 沧桑雨迢迢      
@net
咋说这话捏?

#7楼    回复  引用  查看    

2007-02-04 10:34 by zfphere      
instanceof 指示某对象是否为某类的一个实例。
当我们用 a.prototype = new b() 时,则
var instanceA = new a();时,
instanceA instanceof a 为 true,且 instanceA instanceof b 也为true。

instanceof 对我个人而言,和for语句搭配作判断比较的多。如:
var wishWall = {
wishs :[],
currentWish : null,
paintWishs : function(){
for(var _wish in this.wishs)
{
if(this.wishs[_wish] instanceof wish) //用于判断的部分。
{
this.wishs[_wish].paint();
}
}
}
}

var wish = function(name)
{
this.name = name;
this.paint = function()
{
....//
}
}
wishWall.wishs.push(new wish("AAA"));
wishWall.wishs.push(new wish("BBB"));
wishWall.wishs.push(new wish("CCC"));
wishWall.paintWishs();

#8楼    回复  引用  查看    

2007-02-04 10:48 by Jeffrey Zhao      
@zfphere
instanceof是基于对象编程中非常重要的操作符。

#9楼    回复  引用  查看    

2007-02-04 14:00 by Hunts.C      
受教:)

#10楼    回复  引用  查看    

2007-02-05 09:20 by Cameo      
迢迢 的javascript牛!学习学习

#11楼    回复  引用    

2007-08-31 00:55 by 老杨同志 [未注册用户]
还有一种方法:
function MyClass(name){

}
Myclass.name=""

这个定义的是类属性

前面例子是实例属性

它们有什么区别啊?能说说吗?

#12楼    回复  引用  查看    

2007-08-31 09:25 by zfphere      
to:老杨同志
你可以测下这段代码:
var MyClass = function()
{
this.printName = function()
{
alert(this.name);
}
this.name = "Jerry.Zeng";
}

MyClass.name = "Zfphere";

var instanceClass = new MyClass();
instanceClass.printName();

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-02-04 09:17 编辑过


相关链接: