设为首页
收藏本站
最新电影
您现在的位置: 首页=>后台技术=>脚本特效=>其他 订阅本栏目  
经典__悟透JavaScript
时间: 2008-04-08 16:07:22 阅读次数:17255

第 1 页 经典__悟透JavaScript[1]
第 2 页 经典__悟透JavaScript[2]
第 3 页 经典__悟透JavaScript[3]
第 4 页 经典__悟透JavaScript[4]
第 5 页 经典__悟透JavaScript[5]
第 6 页 经典__悟透JavaScript[6]
第 7 页 经典__悟透JavaScript[7]
第 8 页 经典__悟透JavaScript[8]
第 9 页 经典__悟透JavaScript[9]
第 10 页 经典__悟透JavaScript[10]
第 11 页 经典__悟透JavaScript[11]


初看原型

prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义。JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理解为C++的prototype那种预先声明的概念。

JavaScript的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个object类型的对象,因此我们也可以给这个prototype对象添加任意的属性和方法。既然prototype是对象的“原型”,那么由该函数构造出来的对象应该都会具有这个“原型”的特性。事实上,在构造函数的prototype上定义的所有属性和方法,都是可以通过其构造的对象直接访问和调用的。也可以这么说,prototype提供了一群同类对象共享属性和方法的机制。

我们先来看看下面的代码:

function Person(name)
{
this.name = name; //设置对象属性,每个对象各自一份属性数据 };

Person.prototype.SayHello
= function() //给Person函数的prototype添加SayHello方法。 {
alert(
"Hello, I'm " + this.name);
}

var BillGates = new Person("Bill Gates"); //创建BillGates对象 var SteveJobs = new Person("Steve Jobs"); //创建SteveJobs对象
BillGates.SayHello();
//通过BillGates对象直接调用到SayHello方法 SteveJobs.SayHello(); //通过SteveJobs对象直接调用到SayHello方法
alert(BillGates.SayHello
== SteveJobs.SayHello); //因为两个对象是共享prototype的SayHello,所以显示:true
飞飞Asp.技术乐园
程序运行的结果表明,构造函数的prototype上定义的方法确实可以通过对象直接调用到,而且代码是共享的。显然,把方法设置到prototype的写法显得优雅多了,尽管调用形式没有变,但逻辑上却体现了方法与类的关系,相对前面的写法,更容易理解和组织代码。

那么,对于多层次类型的构造函数情况又如何呢?

我们再来看下面的代码:

1 function Person(name) //基类构造函数 2 {
3 this.name = name;
4 };
5
6 Person.prototype.SayHello = function() //给基类构造函数的prototype添加方法 7 {
8 alert("Hello, I'm " + this.name);
9 };
10
11 function Employee(name, salary) //子类构造函数12 {
13 Person.call(this, name); //调用基类构造函数14 this.salary = salary;
15 };
16
17 Employee.prototype = new Person(); //建一个基类的对象作为子类原型的原型,这里很有意思18
19 Employee.prototype.ShowMeTheMoney = function() //给子类添构造函数的prototype添加方法20 {
21 alert(this.name + " $" + this.salary);
22 };
23 24 var BillGates = new Person("Bill Gates"); //创建基类Person的BillGates对象25 var SteveJobs = new Employee("Steve Jobs", 1234); //创建子类Employee的SteveJobs对象26 27 BillGates.SayHello(); //通过对象直接调用到prototype的方法28 SteveJobs.SayHello(); //通过子类对象直接调用基类prototype的方法,关注!29 SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类prototype的方法30 31 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明prototype的方法是共享的

这段代码的第17行,构造了一个基类的对象,并将其设为子类构造函数的prototype,这是很有意思的。这样做的目的就是为了第28行,通过子类对象也可以直接调用基类prototype的方法。为什么可以这样呢?

原来,在JavaScript中,prototype不但能让对象共享自己财富,而且prototype还有寻根问祖的天性,从而使得先辈们的遗产可以代代相传。当从一个对象那里读取属性或调用方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找;如果prototype没有,又会去prototype自己关联的前辈prototype那里寻找,直到找到或追溯过程结束为止。

在JavaScript内部,对象的属性和方法追溯机制是通过所谓的prototype链来实现的。当用new操作符构造对象时,也会同时将构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。对象内置的原型对象应该是对外不可见的,尽管有些浏览器(如Firefox)可以让我们访问这个内置原型对象,但并不建议这样做。内置的原型对象本身也是对象,也有自己关联的原型对象,这样就形成了所谓的原型链。

在原型链的最末端,就是Object构造函数prototype属性指向的那一个原型对象。这个原型对象是所有对象的最老祖先,这个老祖宗实现了诸如toString等所有对象天生就该具有的方法。其他内置构造函数,如Function, Boolean, String, Date和RegExp等的prototype都是从这个老祖宗传承下来的,但他们各自又定义了自身的属性和方法,从而他们的子孙就表现出各自宗族的那些特征。

这不就是“继承”吗?是的,这就是“继承”,是JavaScript特有的“原型继承”。

“原型继承”是慈祥而又严厉的。原形对象将自己的属性和方法无私地贡献给孩子们使用,也并不强迫孩子们必须遵从,允许一些顽皮孩子按自己的兴趣和爱好独立行事。从这点上看,原型对象是一位慈祥的母亲。然而,任何一个孩子虽然可以我行我素,但却不能动原型对象既有的财产,因为那可能会影响到其他孩子的利益。从这一点上看,原型对象又象一位严厉的父亲。我们来看看下面的代码就可以理解这个意思了:
function Person(name)
{
this.name = name;
};

Person.prototype.company
= "Microsoft"; //原型的属性
Person.prototype.SayHello
= function() //原型的方法 {
alert(
"Hello, I'm " + this.name + " of " + this.company);
};

var BillGates = new Person("Bill Gates");
BillGates.SayHello();
//由于继承了原型的东西,规规矩矩输出:Hello, I'm Bill Gates
var SteveJobs = new Person("Steve Jobs");
SteveJobs.company
= "Apple"; //设置自己的company属性,掩盖了原型的company属性 SteveJobs.SayHello = function() //实现了自己的SayHello方法,掩盖了原型的SayHello方法 {
alert(
"Hi, " + this.name + " like " + this.company + ", ha ha ha ");
};

SteveJobs.SayHello();
//都是自己覆盖的属性和方法,输出:Hi, Steve Jobs like Apple, ha ha ha
BillGates.SayHello();
//SteveJobs的覆盖没有影响原型对象,BillGates还是按老样子输出


对象可以掩盖原型对象的那些属性和方法,一个构造函数原型对象也可以掩盖上层构造函数原型对象既有的属性和方法。这种掩盖其实只是在对象自己身上创建了新的属性和方法,只不过这些属性和方法与原型对象的那些同名而已。JavaScript就是用这简单的掩盖机制实现了对象的“多态”性,与静态对象语言的虚函数和重载(override)概念不谋而合。

然而,比静态对象语言更神奇的是,我们可以随时给原型对象动态添加新的属性和方法,从而动态地扩展基类的功能特性。这在静态对象语言中是很难想象的。我们来看下面的代码:



function Person(name)
{
this.name = name;
};

Person.prototype.SayHello
= function() //建立对象前定义的方法 {
alert(
"Hello, I'm " + this.name);
};

var BillGates = new Person("Bill Gates"); //建立对象
BillGates.SayHello();

Person.prototype.Retire
= function() //建立对象后再动态扩展原型的方法 {
alert(
"Poor " + this.name + ", bye bye!");
};

BillGates.Retire();
//动态扩展的方法即可被先前建立的对象立即调用
飞飞As~p技术乐园
阿弥佗佛,原型继承竟然可以玩出有这样的法术!



[上一页] [下一页]
本站下载资源全部放在fs2you共享空间上,若不能正常下载以上资源,请下载修复补丁
下载"经典__悟透JavaScript"Word版
点击下载
站内搜索    

下一篇飞飞input表单输入框默认提示信息插件

上一篇用键盘打开网页代码

本栏目最新 栏目最新列表
xhEditor v1.1.7 发布,国产开源XHTML在线编
收集的一些轻量级非常实用的前端开发小工具
javascript中cookie的设置,读取,删除
jquery插件:飞飞表情插件v1.0_[普通表情/魔
Jquery插件:textarea使用“autoresize”自
网站优化策划 栏目最新列表
增加网站外链的快速方法
网站上线前必做的30个检查
新的友情链接参考标准(没有google的PR情况
优化Google的AdSense广告的五个工具
王通讲SEO八大基础
站点最新 站点最新列表
微博推广的一些技巧
xhEditor v1.1.7 发布,
收集的一些轻量级非常实
50个新鲜兼容最新版本的
javascript中cookie的设
Excel中出现#VALUE!、#D
jquery插件:飞飞表情插件
十个使用HTML5开发的精彩
支持HTML5的浏览器有哪些
飞妮莫属:漫画:如何写出
历史最热10条信息  
MIME介绍 及 [1] [2] [3]
巧用Google和迅雷来下载
Transact SQL 常 [1] [2]
VIA Rhine II Fast Ethe
电脑常用端 [1] [2] [3]
Do you get a kick out
十道羊皮卷 欣赏+mp3版+
每日一句:A friend and
每日一句:Theres no tu
经典__悟透JavaScript
 width= 
伟哥博客 西安房产 123最新电影 三四六四