JavaScript的面向对象机理
2008-01-09 10:27
447 查看
JavaScript的面向对象机理1)-类
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原型对象.
JavaScript的面向对象机理2)-继承
一个继承机制可以有多简单?
以下是一个最简单的实现继承基类属性和方法的示例:
<script type="text/javascript">
//声明继承自哪一个基类
Function.prototype.extend = function(baseClass)
{
this.baseClass = baseClass;
}
//初始化基类的属性(其实这个函数才具体实现"继承"基类属性和方法)
Function.prototype.initializeBase = function()
{
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
//定义一个基类
function MyBase(name)
{
this.name = name;
this.showName = function()
{
alert(this.name);
}
}
//定义一个扩展类
function MyClass(name,age)
{
MyClass.initializeBase(this,[name]);//初始化基类
this.age = age;
this.showAge = function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);//声明继承自MyBase
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
这里对initializeBase方法的注释是"初始化基类",但其实initializeBase的更重要的功能是"继承"的具体实现.没有这个方法的调用,即使你用extend方法声明过了继承自哪一个类了,但是基类的属性在派生类中还是没有得到真正的"赋予".
这种类的设计方式是依赖于JavaScript的动态属性扩展能力而实现的,因此这种方式的继承机制,不是在于"基类"与"派生类"之间的属性/方法继承,"派生类"其实与"基类"没关系,"派生类"只是通过extend而知道了自己的基类,具体的基类的属性和方法,要由被实例化的对象自己去基类的构造函数那获取.
这种继承实现方式如果非要用一个比喻来形容的话,就仿佛是...应该是你的老板A直接付你工资,但是他不,他不乐意(我靠!).他说某老板B欠他钱,他有凭据(A.extend(B)),他要求你去找B要去(A.initializeBase(this)),幸好,B还算有信,二话不说给了你钱(B.apply(self,[...]).
:)
真正的派生类与基类之间继承
要实现真正的,派生类通过extend方法就完全获得基类的属性和方法,则必须依靠prototype,这也是类定义的两种方法之一.具体请看如下示例:
<script type="text/javascript">
Function.prototype.extend = function(baseClass)
{
for(var ptototypeName in baseClass.prototype)
{
if(typeof(this.prototype[ptototypeName]) === 'undefined')
{
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
function MyBase(name)
{
}
MyBase.prototype =
{
name: null,
showName: function()
{
alert(this.name);
}
}
function MyClass(name,age)
{
this.name = name;
this.age = age;
}
MyClass.prototype =
{
age: null,
showAge: function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
此时,MyClass在extend的时候,就从MyBase那完全获取了属性和方法(这些属性和方法定义在prototype上).因此,可以直接通过prototype的内建功能把属性和方法赋予MyClass所创建的实例上了.
还是那个比喻...你的老板A幡然悔悟,他强烈要求即时付你工钱,决不让你自己去讨要第三方欠他的债...因此你就不同到B那跑一趟了,尽管B这人还是不错的...
继承机制的完美实现
其实就是把上面的两种方法结合起来...
如下:
<script type="text/javascript">
Function.prototype.extend = function(baseClass)
{
this.baseClass = baseClass;
for(var ptototypeName in baseClass.prototype)
{
if(typeof(this.prototype[ptototypeName]) === 'undefined')
{
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
Function.prototype.initializeBase = function()
{
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
function MyBase(name,sex)
{
this.name = name;
this.sex = !!sex;
this.showSex = function()
{
if(!!sex)
{
alert("男");
}else
{
alert("女");
}
}
}
MyBase.prototype =
{
name: null,
showName: function()
{
alert(this.name);
}
}
function MyClass(name,age,sex)
{
MyClass.initializeBase(this,[name,sex]);
this.age = age;
}
MyClass.prototype =
{
age: null,
showAge: function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25,true);
m.showName();
m.showAge();
m.showSex();
</script>
现在,你的老板A又改了策略.他顾及舆论的压力,直接付了你一点钱,另外一部分,还是要你去找欠他款的B要...ok,你可以去见B了,B还是很讲信用滴~~~当然你要祈祷没有欠B款的C,否则你会去找C的...一直......
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原型对象.
JavaScript的面向对象机理2)-继承
一个继承机制可以有多简单?
以下是一个最简单的实现继承基类属性和方法的示例:
<script type="text/javascript">
//声明继承自哪一个基类
Function.prototype.extend = function(baseClass)
{
this.baseClass = baseClass;
}
//初始化基类的属性(其实这个函数才具体实现"继承"基类属性和方法)
Function.prototype.initializeBase = function()
{
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
//定义一个基类
function MyBase(name)
{
this.name = name;
this.showName = function()
{
alert(this.name);
}
}
//定义一个扩展类
function MyClass(name,age)
{
MyClass.initializeBase(this,[name]);//初始化基类
this.age = age;
this.showAge = function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);//声明继承自MyBase
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
这里对initializeBase方法的注释是"初始化基类",但其实initializeBase的更重要的功能是"继承"的具体实现.没有这个方法的调用,即使你用extend方法声明过了继承自哪一个类了,但是基类的属性在派生类中还是没有得到真正的"赋予".
这种类的设计方式是依赖于JavaScript的动态属性扩展能力而实现的,因此这种方式的继承机制,不是在于"基类"与"派生类"之间的属性/方法继承,"派生类"其实与"基类"没关系,"派生类"只是通过extend而知道了自己的基类,具体的基类的属性和方法,要由被实例化的对象自己去基类的构造函数那获取.
这种继承实现方式如果非要用一个比喻来形容的话,就仿佛是...应该是你的老板A直接付你工资,但是他不,他不乐意(我靠!).他说某老板B欠他钱,他有凭据(A.extend(B)),他要求你去找B要去(A.initializeBase(this)),幸好,B还算有信,二话不说给了你钱(B.apply(self,[...]).
:)
真正的派生类与基类之间继承
要实现真正的,派生类通过extend方法就完全获得基类的属性和方法,则必须依靠prototype,这也是类定义的两种方法之一.具体请看如下示例:
<script type="text/javascript">
Function.prototype.extend = function(baseClass)
{
for(var ptototypeName in baseClass.prototype)
{
if(typeof(this.prototype[ptototypeName]) === 'undefined')
{
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
function MyBase(name)
{
}
MyBase.prototype =
{
name: null,
showName: function()
{
alert(this.name);
}
}
function MyClass(name,age)
{
this.name = name;
this.age = age;
}
MyClass.prototype =
{
age: null,
showAge: function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25);
m.showName();
m.showAge();
</script>
此时,MyClass在extend的时候,就从MyBase那完全获取了属性和方法(这些属性和方法定义在prototype上).因此,可以直接通过prototype的内建功能把属性和方法赋予MyClass所创建的实例上了.
还是那个比喻...你的老板A幡然悔悟,他强烈要求即时付你工钱,决不让你自己去讨要第三方欠他的债...因此你就不同到B那跑一趟了,尽管B这人还是不错的...
继承机制的完美实现
其实就是把上面的两种方法结合起来...
如下:
<script type="text/javascript">
Function.prototype.extend = function(baseClass)
{
this.baseClass = baseClass;
for(var ptototypeName in baseClass.prototype)
{
if(typeof(this.prototype[ptototypeName]) === 'undefined')
{
this.prototype[ptototypeName] = baseClass.prototype[ptototypeName];
}
}
}
Function.prototype.initializeBase = function()
{
if(typeof(this.baseClass) === 'undefined') return;
var self = arguments[0];
if(!self) return;
this.baseClass.apply(self,arguments[1]);
}
function MyBase(name,sex)
{
this.name = name;
this.sex = !!sex;
this.showSex = function()
{
if(!!sex)
{
alert("男");
}else
{
alert("女");
}
}
}
MyBase.prototype =
{
name: null,
showName: function()
{
alert(this.name);
}
}
function MyClass(name,age,sex)
{
MyClass.initializeBase(this,[name,sex]);
this.age = age;
}
MyClass.prototype =
{
age: null,
showAge: function()
{
alert(this.age);
}
}
MyClass.extend(MyBase);
var m = new MyClass("fanrong",25,true);
m.showName();
m.showAge();
m.showSex();
</script>
现在,你的老板A又改了策略.他顾及舆论的压力,直接付了你一点钱,另外一部分,还是要你去找欠他款的B要...ok,你可以去见B了,B还是很讲信用滴~~~当然你要祈祷没有欠B款的C,否则你会去找C的...一直......
相关文章推荐
- JavaScript的面向对象机理1)-类
- JavaScript的面向对象机理2)-继承
- JavaScript 面向对象开发
- web前端开发笔记:JavaScript面向对象总结
- JavaScript面向对象程序设计(7): 闭包
- JavaScript模拟面向对象
- 学习javascript面向对象 实例讲解面向对象选项卡
- JavaScript 与面向对象实战.
- JavaScript 面向对象代码实践
- Javascript高级程序设计第二版第六章--面向对象程序设计(Object-Oriented Programming)简称OOP编程--笔记
- 关于JavaScript的面向对象和继承有利新手学习
- javascript_面向对象系列_03弹力球(ES3)
- javascript面向对象基础——作用域、闭包、模拟私有属性
- 理清一下JavaScript面向对象思路
- javascript面向对象包装类Class封装类库剖析
- JavaScript 面向对象程序设计(下)——继承与多态
- javascript面向对象创建高级 Web 应用程序
- JavaScript高级程序设计学习笔记--面向对象程序设计
- JavaScript面向对象分层思维全面解析
- JavaScript面向对象初步