文章探索:   分类:    关键字:  
  + 栏目导航
  + 相关文章
document 对象
Window.Open详解
JS replace 方法
JScript 属性
JScript 对象
JScript 方法
关于window.opener的用法
JavaScript语法——style.display 属..
不被拦截的弹出窗口代码
showModalDialog和showModelessDialog..
showModelessDialog()使用详解
IE中非模式对话框(showModelessDialog..
JS eval()函数
Preferences 指南
JS中的setTimeout和setInterval的区别
JavaScript对象与数组参考大全
javascript动态增加、删除、填充表格..
用Java实现几种常见的排序算法
JavaScript 日期函数
JavaScript 使用字符串函数
如何用Javascript获得TextArea中的光..
Document 对象方法
在input中只能输入数字
selection.createRange() 用法例子
获取网页各种宽高的值
JavaScript方法 - indexOf方法
substring函数详解
40种网页常用小技巧(javascript)
event.X和event.clientX有什么区别
clientX, clientY,offsetX, offsetY,..


技术教程 -> JavaScript教程 ->  
JavaScript面向对象的支持(1)
来源:转载   人气:721   录入时间:2007-11-8
    
   Qomolangma OpenProject v0.9
   
   
   类别 :Rich Web Client
   关键词 :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component,
    DOM,DTHML,CSS,JavaScript,JScript
   
   项目发起:aimingoo (aim@263.net)
   项目团队:aimingoo, leon(pfzhou@gmail.com)
   有贡献者:JingYu(zjy@cnpack.org)
   ================================================================================
   
   
   八、JavaScript面向对象的支持
   ~~~~~~~~~~~~~~~~~~
   很少有人对JavaScript的面向对象特性进行系统的分析。我希望接下来的文字让你了解到这
   个语言最少为人知的一面。
   
   
   1. JavaScript中的类型
   --------
   虽然JavaScript是一个基于对象的语言,但对象(Object)在JavaScript中不是第一型的。JS
   是以函数(Function)为第一型的语言。这样说,不但是因为JS中的函数具有高级语言中的函
   数的各种特性,而且也因为在JS中,Object也是由函数来实现的。——关于这一点,可以在
   后文中“构造与析构”部分看到更进一步的说明。
   
   JS中是弱类型的,他的内置类型简单而且清晰:
   ---------------------------------------------------------
   undefined : 未定义
   number : 数字
   boolean : 布尔值
   string : 字符串
   function : 函数
   object : 对象
   
   
    1). undefined类型
   ========================
   在IE5及以下版本中,除了直接赋值和typeof()之外,其它任何对undefined的操作都将导致
   异常。如果需要知道一个变量是否是undefined,只能采用typeof()的方法:
   <script>
   var v;
   if (typeof(v) == 'undefined') {
    // ...
   }
   </script>
   
   但是在IE5.5及以上版本中,undefined是一个已实现的系统保留字。因此可以用undefined来
   比较和运算。检测一个值是否是undefined的更简单方法可以是:
   <script>
   var v;
   if (v === undefined) {
    // ...
   }
   </script>
   
   因此为了使得核心代码能(部分地)兼容IE5及早期版本,Romo核心单元中有一行代码用来
   “声明”一个undefined值:
   //---------------------------------------------------------
   // code from Qomolangma, in JSEnhance.js
   //---------------------------------------------------------
   var undefined = void null;
   
   这一行代码还有一点是需要说明的,就是void语句的应用。void表明“执行其后的语句,且
   忽略返回值”。因此在void之后可以出现能被执行的任何“单个”语句。而执行的结果就是
   undefined。当然,如果你愿意,你也可以用下面的代码之一“定义undefined”。
   //---------------------------------------------------------
   // 1. 较复杂的方法,利用一个匿名的空函数执行的返回
   //---------------------------------------------------------
   var undefined = function(){}();
   
   //---------------------------------------------------------
   // 2. 代码更简洁,但不易懂的方法
   //---------------------------------------------------------
   var undefined = void 0;
   
   void也能像函数一样使用,因此void(0)也是合法的。有些时候,一些复杂的语句可能不能
   使用void的关键字形式,而必须要使用void的函数形式。例如:
   //---------------------------------------------------------
   // 必须使用void()形式的复杂表达式
   //---------------------------------------------------------
   void(i=1); // 或如下语句:
   void(i=1, i++);
   
   
    2). number类型
   ========================
   JavaScript中总是处理浮点数,因此它没有象Delphi中的MaxInt这样的常量,反而是有这
   样两个常值定义:
    Number.MAX_VALUE : 返回 JScript 能表达的最大的数。约等于 1.79E+308。
    Number.MIN_VALUE : 返回 JScript 最接近0的数。约等于 2.22E-308。
   
   因为没有整型的缘故,因此在一些关于CSS和DOM属性的运算中,如果你期望取值为整数2,
   你可能会得到字符串“2.0”——或者类似于此的一些情况。这种情况下,你可能需要用
   到全局对象(Gobal)的parseInt()方法。
   
   全局对象(Gobal)中还有两个属性与number类型的运算有关:
    NaN : 算术表达式的运算结果不是数字,则返回NaN值。
    Infinity : 比MAX_VALUE更大的数。
   
   如果一个值是NaN,那么他可以通过全局对象(Gobal)的isNaN()方法来检测。然而两个NaN
   值之间不是互等的。如下例:
   //---------------------------------------------------------
   // NaN的运算与检测
   //---------------------------------------------------------
   var
    v1 = 10 * 'a';
    v2 = 10 * 'a';
   document.writeln(isNaN(v1));
   document.writeln(isNaN(v2));
   document.writeln(v1 == v2);
   
   全局对象(Gobal)的Infinity表示比最大的数 (Number.MAX_VALUE) 更大的值。在JS中,
   它在数学运算时的价值与正无穷是一样的。——在一些实用技巧中,它也可以用来做一
   个数组序列的边界检测。
   
   Infinity在Number对象中被定义为POSITIVE_INFINITY。此外,负无穷也在Number中被定
   义:
    Number.POSITIVE_INFINITY : 比最大正数(Number.MAX_VALUE)更大的值。正无穷。
    Number.NEGATIVE_INFINITY : 比最小负数(-Number.MAX_VALUE)更小的值。负无穷。
   
   与NaN不同的是,两个Infinity(或-Infinity)之间是互等的。如下例:
   //---------------------------------------------------------
   // Infinity的运算与检测
   //---------------------------------------------------------
   var
    v1 = Number.MAX_VALUE * 2;
    v2 = Number.MAX_VALUE * 3;
   document.writeln(v1);
   document.writeln(v2);
   document.writeln(v1 == v2);
   
   在Global中其它与number类型相关的方法有:
    isFinite() : 如果值是NaN/正无穷/负无穷,返回false,否则返回true。
    parseFloat() : 从字符串(的前缀部分)取一个浮点数。不成功则返回NaN。
   
   
    3). boolean类型
   ========================
    (略)
   
    4). string类型
   ========================
   JavaScript中的String类型原本没有什么特殊的,但是JavaScript为了适应
   “浏览器实现的超文本环境”,因此它具有一些奇怪的方法。例如:
    link() : 把一个有HREF属性的超链接标签<A>放在String对象中的文本两端。
    big() : 把一对<big>标签放在String对象中的文本两端。
   以下方法与此类同:
    anchor()
    blink()
    bold()
    fixed()
    fontcolor()
    fontsize()
    italics()
    small()
    strike()
    sub()
    sup()
   
   除此之外,string的主要复杂性来自于在JavaScript中无所不在的toString()
   方法。这也是JavaScript为浏览器环境而提供的一个很重要的方法。例如我们
   声明一个对象,但是要用document.writeln()来输出它,在IE中会显示什么呢?
   
   下例说明这个问题:
   //---------------------------------------------------------
   // toString()的应用
   //---------------------------------------------------------
   var
    s = new Object();
   
   s.v1 = 'hi,';
   s.v2 = 'test!';
   document.writeln(s);
   document.writeln(s.toString());
   
   s.toString = function() {
    return s.v1 + s.v2;
   }
   document.writeln(s);
   
   在这个例子中,我们看到,当一个对象没有重新声明(覆盖)自己toString()方
   法的时候,那么它作为字符串型态使用时(例如被writeln),就会调用Java Script
   环境缺省的toString()。反过来,你也可以重新定义JavaScript理解这个对象
   的方法。
   
   很多JavaScript框架,在实现“模板”机制的时候,就利用了这个特性。例如
   他们用这样定义一个FontElement对象:
   //---------------------------------------------------------
   // 利用toString()实现模板机制的简单原理
   //---------------------------------------------------------
   function FontElement(innerHTML) {
    this.face = '宋体';
    this.color = 'red';
    // more...
   
    var ctx = innerHTML;
    this.toString = function() {
    return '<Font FACE="' + this.face + '" COLOR="' + this.color + '">'
    + ctx
    + '</FONT>';
    }
   }
   
   var obj = new FontElement('这是一个测试。');
   
   // 留意下面这行代码的写法
   document.writeln(obj);
   
   
    5). function类型
   ========================
   javascript函数具有很多特性,除了面向对象的部分之外(这在后面讲述),它自
   已的一些独特特性应用也很广泛。
   
   首先javascript中的每个函数,在调用过程中可以执有一个arguments对象。这个
   对象是由脚本解释环境创建的,你没有别的方法来自己创建一个arguments对象。
   
   arguments可以看成一个数组:它有length属性,并可以通过arguments[n]的方式
   来访问每一个参数。然而它最重要的,却是可以通过 callee 属性来得到正在执行
   的函数对象的引用。
   
   接下的问题变得很有趣:Function对象有一个 caller 属性,指向正在调用当前
   函数的父函数对象的引用。
   
   ——我们已经看到,我们可以在JavaScript里面,通过callee/caller来遍历执行
   期的调用栈。由于arguments事实上也是Function的一个属性,因此我们事实上也
   能遍历执行期调用栈上的每一个函数的参数。下面的代码是一个简单的示例:
   
   //---------------------------------------------------------
   // 调用栈的遍历
   //---------------------------------------------------------
   function foo1(v1, v2) {
    foo2(v1 * 100);
   }
   
   function foo2(v1) {
    foo3(v1 * 200);
   }
   
   function foo3(v1) {
    var foo = arguments.callee;
    while (foo && (foo != window)) {
    document.writeln('调用参数:<br>', '---------------<br>');
   
    var args = foo.arguments, argn = args.length;
    for (var i=0; i<argn; i++) {
    document.writeln('args[', i, ']: ', args[i], '<br>');
    }
    document.writeln('<br>');
   
    // 上一级
    foo = foo.caller;
    }
   }
   
   // 运行测试
   foo1(1, 2);
   
   
   2. JavaScript面向对象的支持
   --------
   在前面的例子中其实已经讲到了object类型的“类型声明”与“实例创建”。
   在JavaScript中,我们需要通过一个函数来声明自己的object类型:
   //---------------------------------------------------------
   // JavaScript中对象的类型声明的形式代码
   // (以后的文档中,“对象名”通常用MyObject来替代)
   //---------------------------------------------------------
   function 对象名(参数表) {
    this.属性 = 初始值;
   
    this.方法 = function(方法参数表) {
    // 方法实现代码
    }
   }
   
   
   然后,我们可以通过这样的代码来创建这个对象类型的一个实例:
   //---------------------------------------------------------
   // 创建实例的形式代码
   // (以后的文档中,“实例变量名”通常用obj来替代)
   //---------------------------------------------------------
   var 实例变量名 = new 对象名(参数表);
   
   
   接下来我们来看“对象”在JavaScript中的一些具体实现和奇怪特性。
   
    1). 函数在JavaScript的面向对象机制中的五重身份
    ------
   “对象名”——如MyObject()——这个函数充当了以下语言角色:
    (1) 普通函数
    (2) 类型声明
    (3) 类型的实现
    (4) 类引用
    (5) 对象的构造函数
   
   一些程序员(例如Delphi程序员)习惯于类型声明与实现分开。例如在delphi
   中,Interface节用于声明类型或者变量,而implementation节用于书写类型
   的实现代码,或者一些用于执行的函数、代码流程。
   
   但在JavaScript中,类型的声明与实现是混在一起的。一个对象的类型(类)
   通过函数来声明,this.xxxx表明了该对象可具有的属性或者方法。
   
   
   这个函数的同时也是“类引用”。在JavaScript,如果你需要识别一个对象
   的具体型别,你需要执有一个“类引用”。——当然,也就是这个函数的名
   字。instanceof 运算符就用于识别实例的类型,我们来看一下它的应用:
   //---------------------------------------------------------
   // JavaScript中对象的类型识别
   // 语法: 对象实例 instanceof 类引用
   //---------------------------------------------------------
   function MyObject() {
    this.data = 'test data';
   }
   
   // 这里MyObject()作为构造函数使用
   var obj = new MyObject();
   var arr = new Array();
   
   // 这里MyObject作为类引用使用
   document.writeln(obj instanceof MyObject);
   document.writeln(arr instanceof MyObject);
   
   
   ================
   (未完待续)
   ================
   接下来的内容:
   
   2. JavaScript面向对象的支持
   --------
   
    2). 反射机制在JavaScript中的实现
    3). this与with关键字的使用
    4). 使用in关键字的运算
    5). 使用instanceof关键字的运算
    6). 其它与面向对象相关的关键字
   
   
   3. 构造与析构
   
   4. 实例和实例引用
   
   5. 原型问题
   
   6. 函数的上下文环境
   
   7. 对象的类型检查问题
   
   




Copyright(C)2007-2024 广州市佳沛数码科技有限公司 版权所有
公司地址: 广州市荔湾区东漖北路560号511室
电话:020-81803473 传真:020-81544987