- 浏览: 1344494 次
- 性别:
- 来自: 湖南澧縣
-
文章分类
最新评论
-
虾米小尹:
不行啊!2.2-0.25=1.9500000000000002 ...
JavaScript浮点数运算 —— 精度问题 -
heluping000000:
引用String a= "abc",首先在 ...
String,到底创建了多少个对象? -
mack:
谢谢分享matcher.appendReplacement(s ...
string.replaceAll()中的特殊字符($ \)与matcher.appendReplacement -
wzt3309:
完全理解,比网上其他资料都要详细
String,到底创建了多少个对象? -
u014771876:
Java中十六进制转换 Integer.toHexString()
-
zInherit
利用zInherit库(可以从http://www.nczonline.net/downloads 处下载),不必使用原型链,也可实现方法继承。
Inherit库给Object类添加了两个方法,inheritFrom()和instanceOf()。inheritFrom()方法负担重任,负责复制指定类的所有方法。下面一行代码用原型链使ClassB继承ClassA的方法:
ClassB.prototype = new ClassA();
可用下面代码替换上面的代码:
ClassB.prototype.inheritFrom(ClassA);
inheritFrom() 方法接受一个参数,即要复制的方法所属的类。注意,与原型链相对的是,这种方式并未真正创建要继承的类的实例(具体请参考zInherit源码),这样更安全,开发者也无需担心构造函数的参数。
instanceOf() 方法是instanceof运算符的替代品。因为这种方式根本不使用原型链,所以这行代码无效:
base3 instanceof Base1
但instanceOf()方法弥补了这项损失,与inheritFrom()一起使用,可以跟踪所有的超类:
base3.instanceOf(Base1);
zInherit多层继承具体示例代码如下:
function Base1(base1Name) { this.base1Name = base1Name; if (typeof Base1._initialized == "undefined") { Base1.prototype.getBase1 = function () { alert(this.base1Name); }; Base1._initialized = true; } } //Base2继承Base1 function Base2(base1Name, base2Name) { this.base2Name = base2Name; //使用call方式对属性继承 Base1.call(this, base1Name); if (typeof Base2._initialized == "undefined") { //使用zinherit方式对方法时行复制继承 Base2.prototype.inheritFrom(Base1); Base2.prototype.getBase2 = function () { alert(this.base2Name); }; Base2._initialized = true; } } //Base3继承Base2 function Base3(base1Name, base2Name, base3Name) { this.base3Name = base3Name; //使用call方式对属性继承 Base2.call(this, base1Name, base2Name); if (typeof Base3._initialized == "undefined") { //使用zinherit方式对方法时行复制继承 Base3.prototype.inheritFrom(Base2); Base3.prototype.getBase3 = function () { alert(this.base3Name); }; Base3._initialized = true; } } var base3 = new Base3("base1Name", "base2Name", "base3Name"); //Base3可以访问从父类Base2继承过来的方法 base3.getBase2();//base2Name //Base3可以访问从超类Base1继承过来的方法 base3.getBase1();//base1Name //当然更可以访问自己的方法 base3.getBase3();//base1Name //因为zinherit方式未采用原型链的方法,所以不支持instanceof alert(base3 instanceof Base1);//false //但可以用zinherit的instanceOf方法来避免该问题 alert(base3.instanceOf(Base1));//true alert(base3.instanceOf(Base2));//true alert(base3.instanceOf(Base3));//true
另外:原型链不能实现动态原型主旨,即把类的所有代码放置在它的构造函数中。zInherit库修正了这个问题,它允许在构造函数内部调用 inheritFrom()方法,使用inheritFrom()方法时,并未重写prototype对象,只是为其加入方法而已(从zInherit源码分析可知)。使用这种方法,即可避开原型链的限制,实现动态原型本意。所以zInherit支持动态原型,从上面的示例就可以看得出来。
zInherit的另一个好处就是除了支持多层继承、动态原型法,还支持多重继承,即一个类可以继承多个类,这些类是同一级别的。
zInherit多重继承示例如下,显示的结果与多层继承一样:
function Base1(base1Name) { this.base1Name = base1Name; if (typeof Base1._initialized == "undefined") { Base1.prototype.getBase1 = function () { alert(this.base1Name); }; Base1._initialized = true; } } function Base2(base2Name) { this.base2Name = base2Name; if (typeof Base2._initialized == "undefined") { Base2.prototype.getBase2 = function () { alert(this.base2Name); }; Base2._initialized = true; } } //多重继承:Base3继承Base1与Base2 function Base3(base1Name, base2Name, base3Name) { this.base3Name = base3Name; //使用call方式对属性继承 Base1.call(this, base1Name); Base2.call(this, base2Name); if (typeof Base3._initialized == "undefined") { //使用zinherit方式对方法时行复制继承 Base3.prototype.inheritFrom(Base1); Base3.prototype.inheritFrom(Base2); Base3.prototype.getBase3 = function () { alert(this.base3Name); }; Base3._initialized = true; } } var base3 = new Base3("base1Name", "base2Name", "base3Name"); //Base3可以访问从父类Base2继承过来的方法 base3.getBase2();//base2Name //Base3可以访问从超类Base1继承过来的方法 base3.getBase1();//base1Name //当然更可以访问自己的方法 base3.getBase3();//base3Name //因为zinherit方式未采用原型链的方法,所以不支持instanceof alert(base3 instanceof Base1);//false //但可以用zinherit的instanceOf方法来避免该问题 alert(base3.instanceOf(Base1));//true alert(base3.instanceOf(Base2));//true alert(base3.instanceOf(Base3));//true
zinherit.js源码分析
/** * Inherits properties and methods from the given class. * @scope public * @param fnClass The constructor function to inherit from. */ Object.prototype.inheritFrom = function (fnClass) { /** * Inherits all classes going up the inheritance chain recursively. * @param fnClass The class to inherit from. * @param arrClasses The array of classes to build up. * @scope private */ function inheritClasses(fnClass, arrClasses) { /* 把父类构造函数放入到子类构造函数的私有属性数组中,用数组实现多继承,即可以继承多个。 此数组里最后存放了所有父类及超类的构造函数,如果子类继承了多个类,则此数组会存储多个构造函数。 */ arrClasses.push(fnClass); //如果父类构造函数继承了其他类,则递归,这样可以实现多层继承 if (typeof fnClass.__superclasses__ == "object") { for (var i = 0; i < fnClass.__superclasses__.length; i++) { //fnClass.__superclasses__[i]为父类的构造函数,如果父类继承了多个类, //则fnClass.__superclasses__.length会大于1 inheritClasses(fnClass.__superclasses__[i], arrClasses); } } } //this为子类构造函数的原型 //this.constructor为子类构造函数 //this.constructor.__superclasses__为子类构造函数的私有属性数组 if (typeof this.constructor.__superclasses__ == "undefined") { //这里的数组用来实现instanceOf用的 this.constructor.__superclasses__ = new Array(); } //fnClass为父类构造函数 inheritClasses(fnClass, this.constructor.__superclasses__); //----上面的操作是为了instanceOf方法应用设计的,下面才是方法继承 //把父类原型里存储的方法复制到子类构造函数原型中(注:这里是方法地址的复制),而不是真真的方法复制 for (prop in fnClass.prototype) { if (typeof fnClass.prototype[prop] == "function") { //this为子类构造函数的原型实例,这里把父类原型实例中的属性(一般指方法属性,但不排除字 //段属性)一一复制到子类构造函数的原型实例中去。而不是采用原型链的方式:Base3.prototype=new Base2(); this[prop] = fnClass.prototype[prop]; } } }; /** * Determines if the given object is an instance of a given class. * This method is necessary because using {@link #inheritFrom} renders * the JavaScript <code>instanceof</code> operator useless. * @param fnClass The constructor function to test. * @return True if the object is an instance of the class, false if not. * @scope public */ Object.prototype.instanceOf = function (fnClass) { //如果是base3.instanceOf(Base3)时 if (this.constructor == fnClass) { return true; //如果是采用zinherit继承方式时,则this.constructor.__superclasses__为数组对象 } else { if (typeof this.constructor.__superclasses__ == "object") { //再进一步判断,如:调用base3.instanceOf(Base1)时 for (var i = 0; i < this.constructor.__superclasses__.length; i++) { if (this.constructor.__superclasses__[i] == fnClass) { return true; } } return false; } else { return false; } } };
-
xbObjects
由 Netscape 公司的 Bob Clary 于 2001 年 Netscape 6 ( Mozilla 0.6 )发布时编写而成。它支持从那时起的所有 Mozilla 版本及其他现代浏览器( IE 、 Opera 和 Safari )。可以从 http://archive.bclary.com/xbProjects-docs/xbObject/ 处下载。
支持继承,还支持方法的重载和调用超类方法的能力。
第一步,必须注册类,此时,需定义它是由哪个类继承而来:
这里,子类和超类名都以字符串形式传进来,而不是指向它们的构造函数的指针 。这个调用必须放在指定子类的构造 函数前 。
如果新的类未继承任何类,调用 registerClass() 时也可以只用第一个参数。
<script type="text/javascript"></script>
第二步 ,在构造函数内调用 defineClass() 方法 ,传给它类名及被 Clary 称为 原型函数 ( prototype function )的指针,该函数用于初始化对象的所有属性和方法 ,例如:
第三步,为该类创建 init() 方法 。该方法负责设置该类的所有属性 ,它必须接受与构造函数相同的参数。作为一种规定, init() 方法总是在 defineClass() 方法后调用 。例如:
init() 方法中调用的 parentMethod() 方法。 xbObjects 以这种方式允许类调用它的超类的方法 。 parentMethod() 方法接受任意多个参数,但第一个参数总是要调用的父类方法的名字(该参数必须是字符串,而不是函数指针),所有其他参数都被传给父类的方法。
在这个例子中,首先调用 init() 方法,这是 xbObjects 运行所必需的。即使 ClassA 未注册超类, xbObejcts 都会为它创建一个所有类的默认超类,即超类方法 init() 所属的类。
第四步 也是最后一步,在原型函数内添加其他类的方法 :
xbObjects多层继承示例如下:
//注册类 _classes.registerClass("Base1"); function Base1(base1Name) { //基于原型来初始化类的属性与方法 function prototypeFunction() { //init方法设置该类的所有属性,它必须接收与构造函数相同的参数签名 Base1.prototype.init = function (base1Name) { //... this.parentMethod("init"); this.base1Name = base1Name; }; //设置方法 Base1.prototype.getBase1 = function () { alert(this.base1Name); }; } //定义类,用来初始化对象所有属性与方法 _classes.defineClass("Base1", prototypeFunction); this.init(base1Name); } //Base2继承Base1 _classes.registerClass("Base2", "Base1"); function Base2(base1Name, base2Name) { function prototypeFunction() { //init方法接收与构造函数相同的参数签名 Base2.prototype.init = function (base1Name, base2Name) { //... this.parentMethod("init", base1Name); this.base2Name = base2Name; }; //设置方法 Base2.prototype.getBase2 = function () { alert(this.base2Name); }; } //定义类,用来初始化对象所有属性与方法 _classes.defineClass("Base2", prototypeFunction); this.init(base1Name, base2Name); } //Base3继承Base2 _classes.registerClass("Base3", "Base2"); function Base3(base1Name, base2Name, base3Name) { function prototypeFunction() { Base3.prototype.init = function (base1Name, base2Name, base3Name) { //... this.parentMethod("init", base1Name, base2Name); this.base3Name = base3Name; }; //设置方法 Base3.prototype.getBase3 = function () { alert(this.base3Name); }; } //定义类,用来初始化对象所有属性与方法 _classes.defineClass("Base3", prototypeFunction); this.init(base1Name, base2Name, base3Name); } var base3 = new Base3("base1Name", "base2Name", "base3Name"); //Base3可以访问从父类Base2继承过来的方法 base3.getBase2();//base2Name //Base3可以访问从超类Base1继承过来的方法 base3.getBase1();//base1Name //当然更可以访问自己的方法 base3.getBase3();//base3Name //因为xbObjects方式未采用原型链的方法,所以不支持instanceof alert(base3 instanceof Base1);//false //但可以用zinherit的instanceOf方法来避免该问题 alert(base3.isInstanceOf(Base1));//true alert(base3.isInstanceOf(Base2));//true alert(base3.isInstanceOf(Base3));//true
注:上面this.parentMethod("init"...)前最好不要加上中文注释,否则可能出问题。
附:zInherit、xbObjects
- zInherit1.0.zip (14.5 KB)
- 下载次数: 8
- xbObjects.rar (2.4 KB)
- 下载次数: 8
发表评论
-
HTML、JS、JSON特殊字符
2010-12-13 23:47 25914JS到HTML特殊字符转换 这几天做项目,发现从服务器端以J ... -
HTML — HTTP URL 中的特殊字符
2009-10-31 18:16 33501. + URL中的+号表示空格 ... -
HTML — CSS选择器
2009-10-25 21:11 2219一个样式规则由两部分组成:选择器和样式声明。选择器表明要为哪一 ... -
部分解决JsUnit无法在firefox3、safari 测试的问题
2009-10-25 07:03 1465在上一篇中出现了一个问题,就是用 jsunit2.2alpha ... -
JsUnit——eclipse插件(四)
2009-10-25 06:59 2478这节我们来看看如何通过JsUnit插件来运行前几节所测试过的测 ... -
10、JavaScript跨浏览器需注意的问题——ajax基础笔记
2009-10-21 22:19 1402向表中追加行 创建表格行时,我们要把创建的 tr 追加到 t ... -
JsUnit详解——Web服务方式(三)
2009-10-21 00:21 2486上两节提到过以Web方式来运行JsUnit,不过不是很详细,这 ... -
JsUnit详解——《ajax基础》笔记(二)
2009-10-20 22:38 2581使用标准/定制查询串 如此说来,测试运行工具是很强大的,但是 ... -
JsUnit详解——《ajax基础》笔记(一)
2009-10-20 19:57 2658JsUnit与JUnit对比 JsUnit也有setUp() ... -
使用Firefox的Web开发插件
2009-10-18 17:53 1492Firefox的Web开发插件为Firefox浏览器增加了大量 ... -
9、访问WEB服务(REST)——ajax基础笔记
2009-10-18 17:24 4080最其名的WEB服务实现是S ... -
8、读取响应头部——ajax基础笔记
2009-10-18 17:20 6784你有时可能需要从服务器获取一些内容,例如,可能想“ping”一 ... -
7、使用JSON向服务器发送数据——ajax基础笔记
2009-10-18 17:20 5262看过前面的例子后(使用XML向服务器发送复杂的数据结构),你可 ... -
6、请求参数作为XML发送——ajax基础笔记
2009-10-18 17:20 1828如果只是使用一个包含 名/值 对的简单查询串,这可能不够健壮, ... -
4、将使用W3C DOM动态生成页面——ajax基础笔记
2009-10-18 17:19 1488使用W3C DOM动态生成页面 dynamicContent ... -
3、将响应解析为XML——ajax基础笔记
2009-10-18 17:18 1089将响应解析为XML parseXML.xml清单: < ... -
2、使用innerHTML属性创建动态内容——ajax基础笔记
2009-10-18 17:17 1983使用innerHTML属性创建动态内容 如果结合作用HTML ... -
1、使用XMLHttpRequest对象——ajax基础笔记
2009-10-18 17:17 2046XMLHttpRequest最早是在 IE5 中以active ... -
30、JavaScript代码优化
2009-10-16 21:25 1633JavaScript代码的速度被分成两部分:下载时间和执行速度 ... -
JavaScript代码优化(二)
2009-10-16 01:32 1221◆字符串的使用 在IE6和IE7中因字符串级联导致的主要问题 ...
相关推荐
`SearchMapIdentityTask`可能是一个自定义的JavaScript类,用于实现对地图上特定区域进行标注的功能。这个功能可以帮助用户在地图上查找、识别和标记特定的地理位置或对象,比如建筑物、道路、兴趣点等。 首先,...
JavaScript代码生成器——Coffee Script CoffeeScript是一种基于Ruby语言的编程语言,旨在通过简洁的编码方式生成JavaScript代码。它结合了Ruby的简洁和JavaScript的灵活性,使开发者可以通过简洁易读的语法撰写...
在“教你一天玩转JavaScript(二)——完成对注册页面的数据的简单校验”这个主题中,我们将深入探讨如何利用JavaScript进行有效的数据验证。 首先,我们需要了解JavaScript的基本语法和特性。JavaScript是一种解释型...
JavaScript凌厉开发——Ext详解与实践 源码 源代码 part3 因为源代码比较大,压缩后76M左右 所以分为四个包上传
JavaScript是一门基于原型的语言,它不像其他面向对象的语言那样具有类的概念,而是通过原型链来实现继承。原型链是JavaScript继承机制的核心,它允许一个对象从另一个对象中继承属性和方法。通过原型链,JavaScript...
此外,教程还会涉及JavaScript的面向对象编程,包括构造函数、原型链、继承和封装。这些概念对于构建大型、复杂的Web应用至关重要。 ES6(ECMAScript 2015)是JavaScript的一个重要版本,引入了许多新特性,如箭头...
在本章中,我们将分析Prototypejs中关于JavaScript继承的实现。 Prototypejs是最早的JavaScript类库,可以说是JavaScript类库的鼻祖。 我在几年前接触的第一个JavaScript类库就是这位,因此Prototypejs有着广泛的...
实验报告的主题是“JavaScript程序设计——DOM访问”,其目的是深入理解和掌握DOM(Document Object Model)在JavaScript中的应用,包括文档对象的属性、方法以及使用方式。DOM是HTML和XML文档的标准化表示,允许...
javascript中如何实现封装,继承和多态
标题中的“Applet与Javascript的对话——让你的Javascript代码和Java Applet融洽地合作”指的是一种技术实现,即如何让JavaScript与Java Applet在Web应用中进行交互。这两种技术在早期Web开发中常常结合使用,以利用...
在这个"JavaScript例子——计算"中,我们可以推测这是一篇关于使用JavaScript进行数学计算的教程或者示例代码。博主"Fuhao9611"在iteye博客上分享了这个主题,可能包含了基础的算术运算、自定义函数、循环结构或者...
在"JavaScript动态网页开发详解——源文件"中,我们可以深入学习到JavaScript在网页开发中的应用技巧。此资料可能包含了JQUERY的官方实例全集,jQuery是一个高效、简洁且富有创造性的JavaScript库,它极大地简化了...
JavaScript还可以通过原型对象来实现继承。 原型对象 在JavaScript中,每个函数对象都有一个prototype属性,该属性指向函数的原型对象。原型对象是一个对象,它包含了构造函数的所有实例对象所共享的属性和方法。...
JavaScript毕业设计——篮球赛事助手源码。已获高分通过项目。 在功能上实现创建比赛,统计参赛人员,统计比赛得分与犯规次数。 安装教程 启动服务器操作 (1) 找到服务器 woao_server 所在文件,点击进去文件 (2...
zinherit库(<script type="text/javascript" src="zinherit.js">)
为了实现JavaScript与Android的交互,我们需要使用`WebViewClient`和`WebChromeClient`。在Activity中,我们这样设置: ```java webView.setWebViewClient(new WebViewClient() { @Override public boolean ...
网页设计与开发——HTML、CSS、JavaScript实例教程网页设计与开发——HTML、CSS、JavaScript实例教程网页设计与开发——HTML、CSS、JavaScript实例教程网页设计与开发——HTML、CSS、JavaScript实例教程网页设计与...
【标题】"网页模板——javascript 在线打字练习"揭示了这个压缩包文件的主要内容,它是一个基于JavaScript技术实现的在线打字练习平台的网页模板。JavaScript,作为全球最广泛使用的编程语言之一,通常用于增强网页...