JavaScript面向对象的支持(2)

发表于:2007-07-01来源:作者:点击数: 标签:
================================================================================ Qomolangma OpenProject v0.9 类别 :Rich Web Client 关键词 :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component, DOM,DTHML,CSS, Java Script,JScript

================================================================================
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)
================================================================================

 2). 反射机制在JavaScript中的实现
 ------
  JavaScript中通过for..in语法来实现了反射机制。但是JavaScript中并不
明确区分“属性”与“方法”,以及“事件”。因此,对属性的类型考查在JS
中是个问题。下面的代码简单示例for..in的使用与属性识别:
//---------------------------------------------------------
// JavaScript中for..in的使用和属性识别
//---------------------------------------------------------
var _r_event = _r_event = /^[Oo]n.*/;
var colorSetting = {
  method: @#red@#,
  event: @#blue@#,
  property: @#@#
}

var obj2 = {
  a_method : function() {},
  a_property: 1,
  onclick: undefined
}

function propertyKind(obj, p) {
  return  (_r_event.test(p) && (obj[p]==undefined || typeof(obj[p])==@#function@#)) ? @#event@#
    : (typeof(obj[p])==@#function@#) ? @#method@#
    : @#property@#;
}

var objectArr = [@#window@#, @#obj2@#];

for (var i=0; i<objectArr.length; i++) {
  document.writeln(@#<p>for @#, objectArr[i], @#<hr>@#);

  var obj = eval(objectArr[i]);
  for (var p in obj) {
    var kind = propertyKind(obj, p);
    document.writeln(@#obj.@#, p, @# is a @#, kind.fontcolor(colorSetting[kind]), @#: @#, obj[p], @#<br>@#);
  }

  document.writeln(@#</p>@#);
}

一个常常被开发者忽略的事实是:JavaScript本身是没有事件(Event)系统的。通常我们在JavaScript用到的onclick等事件,其实是IE的DOM模型提供的。从更内核的角度上讲:IE通过COM的接口属性公布了一组事件接口给DOM。

有两个原因,使得在JS中不能很好的识别“一个属性是不是事件”:

  - COM接口中本身只有方法,属性与事件,都是通过一组get/set方法来公布的。
  - JavaScript中,本身并没有独立的“事件”机制。

因此我们看到event的识别方法,是检测属性名是否是以@#on@#字符串开头(以@#On@#开头的是Qomo的约定)。接下来,由于DOM对象中的事件是可以不指定处理函数的,这种情况下事件句柄为null值(Qomo采用相同的约定);在另外的一些情况下,用户可能象obj2这样,定义一个值为 undefined的事件。因此“事件”的判定条件被处理成一个复杂的表达式:
   ("属性以on/On开头" && ("值为null/undefined" || "类型为function"))

另外,从上面的这段代码的运行结果来看。对DOM对象使用for..in,是不能列举出对象方法来的。

最后说明一点。事实上,在很多语言的实现中,“事件”都不是“面向对象”的语言特性,而是由具体的编程模型来提供的。例如Delphi中的事件驱动机制,是由Win32操作系统中的窗口消息机制来提供,或者由用户代码在Component/Class中主动调用事件处理函数来实现。

“事件”是一个“如何驱动编程模型”的机制/问题,而不是语言本身的问题。然而以PME(property/method/event)为框架的OOP概念,已经深入人心,所以当编程语言或系统表现出这些特性来的时候,就已经没人关心“event究竟是谁实现”的了。


 3). this与with关键字的使用
 ------
 在JavaScript的对象系统中,this关键字用在两种地方:

   - 在构造器函数中,指代新创建的对象实例
   - 在对象的方法被调用时,指代调用该方法的对象实例

 如果一个函数被作为普通函数(而不是对象方法)调用,那么在函数中的this关键字将指向window对象。与此相同的,如果this关键字不在任何函数中,那么他也指向window对象。

 由于在JavaScript中不明确区分函数与方法。因此有些代码看起来很奇怪:
//---------------------------------------------------------
// 函数的几种可能调用形式
//---------------------------------------------------------
function foo() {
  // 下面的this指代调用该方法的对象实例
  if (this===window) {
    document.write(@#call a function.@#, @#<BR>@#);
  }
  else {
    document.write(@#call a method, by object: @#, this.name, @#<BR>@#);
  }
}

 

[1]    

原文转自:http://www.ltesting.net