• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: 小 中 大 | 推荐给好友 上一篇 | 下一篇

JavaScript面向对象的支持(5)

发布: 2007-7-01 18:47 | 作者: admin | 来源: | 查看: 13次 | 进入软件测试论坛讨论

领测软件测试网

八、JavaScript面向对象的支持
~~~~~~~~~~~~~~~~~~
(续)

 4). 需要用户维护的另一个属性:constructor
 ------
 回顾前面的内容,我们提到过:
   - (如果正常地实现继承模型,)对象实例的constructor属性指向构造器
   - obj.constructor.prototype指向该对象的原型
   - 通过Object.constructor属性,可以检测obj2与obj1是否是相同类型的实例

  与原型链要通过用户代码来维护prototype属性一样,实例的构造器属性constructor也需要用户代码维护。

  对于JavaScript的内置对象来说,constructor属性指向内置的构造器函数。如:
//---------------------------------------------------------
// 内置对象实例的constructor属性
//---------------------------------------------------------
var _object_types = {
  @#function@#  : Function,
  @#boolean@#   : Boolean,
  @#regexp@#    : RegExp,
// @#math@#     : Math,
// @#debug@#    : Debug,
// @#image@#    : Image;
// @#undef@#    : undefined,
// @#dom@#      : undefined,
// @#activex@#  : undefined,
  @#vbarray@#   : VBArray,
  @#array@#     : Array,
  @#string@#    : String,
  @#date@#      : Date,
  @#error@#     : Error,
  @#enumerator@#: Enumerator,
  @#number@#    : Number,
  @#object@#    : Object
}

function objectTypes(obj) {
  if (typeof obj !== @#object@#) return typeof obj;
  if (obj === null) return @#null@#;

  for (var i in _object_types) {
    if (obj.constructor===_object_types[i]) return i;
  }
  return @#unknow@#;
}

// 测试数据和相关代码
function MyObject() {
}
function MyObject2() {
}
MyObject2.prototype = new MyObject();

window.execScript(@#@#+
@#Function CreateVBArray()@# +
@#  Dim a(2, 2)@# +
@#  CreateVBArray = a@# +
@#End Function@#, @#VBScript@#);

document.writeln(@#<div id=dom style="display:none">dom<@#, @#/div>@#);

// 测试代码
var ax = new ActiveXObject("Microsoft.XMLHTTP");
var dom = document.getElementById(@#dom@#);
var vba = new VBArray(CreateVBArray());
var obj = new MyObject();
var obj2 = new MyObject2();

document.writeln(objectTypes(vba), @#<br>@#);
document.writeln(objectTypes(ax), @#<br>@#);
document.writeln(objectTypes(obj), @#<br>@#);
document.writeln(objectTypes(obj2), @#<br>@#);
document.writeln(objectTypes(dom), @#<br>@#);

在这个例子中,我们发现constructor属性被实现得并不完整。对于DOM对象、ActiveX对象来说这个属性都没有正确的返回。

确切的说,DOM(包括Image)对象与ActiveX对象都不是标准JavaScript的对象体系中的,因此它们也可能会具有自己的constructor属性,并有着与JavaScript不同的解释。因此,JavaScript中不维护它们的constructor属性,是具有一定的合理性的。

另外的一些单体对象(而非构造器),也不具有constructor属性,例如“Math”和“Debug”、“Global”和“RegExp对象”。他们是JavaScript内部构造的,不应该公开构造的细节。

我们也发现实例obj的constructor指向function MyObject()。这说明JavaScript维护了对象的constructor属性。——这与一些人想象的不一样。

然而再接下来,我们发现MyObject2()的实例obj2的constructor仍然指向function MyObject()。尽管这很说不通,然而现实的确如此。——这到底是为什么呢?

事实上,仅下面的代码:
--------
function MyObject2() {
}

obj2 = new MyObject2();
document.writeln(MyObject2.prototype.constructor === MyObject2);
--------
构造的obj2.constructor将正确的指向function MyObject2()。事实上,我们也会注意到这种情况下,MyObject2的原型属性的constructor也正确的指向该函数。然而,由于JavaScript要求指定prototype对象来构造原型链:
--------
function MyObject2() {
}
MyObject2.prototype = new MyObject();

obj2 = new MyObject2();
--------
这时,再访问obj2,将会得到新的原型(也就是MyObject2.prototype)的constructor属性。因此,一切很明了:原型的属性影响到构造过程对对象的constructor的初始设定。

作为一种补充的解决问题的手段,JavaScript开发规范中说“need to remember to reset the constructor property@#,要求用户自行设定该属性。

所以你会看到更规范的JavaScript代码要求这样书写:
//---------------------------------------------------------
// 维护constructor属性的规范代码
//---------------------------------------------------------
function MyObject2() {
}
MyObject2.prototype = new MyObject();
MyObject2.prototype.constructor = MyObject2;

obj2 = new MyObject2();


更外一种解决问题的方法,是在function MyObject()中去重置该值。当然,这样会使得执行效率稍低一点点:
//---------------------------------------------------------
// 维护constructor属性的第二种方式
//---------------------------------------------------------
function MyObject2() {
  this.constructor = arguments.callee;
  // or, this.constructor = MyObject2;

  // ...
}
MyObject2.prototype = new MyObject();

obj2 = new MyObject2();

 

[1]    

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:[email protected] 电话:010-51297073

软件测试 | 领测国际 | ISTQB | ISTQB官网 | TMMi | TMMi认证 | 国际软件测试工程师认证 | 领测软件测试网