分享

javascript 的几个 tip

 duduwolf 2005-08-07
1、JavaScript 中的继承
在 JavaScript 中实现继承的方法是:将子类的 prototype 属性设置为父类的对象。
例如,我有一个 Basket 类,继承 Hashtable 类:
java代码: 

Basket.prototype = new Hashtable();
Basket.prototype.constructor = Basket;


如果不写上面第二句,以后 typeof 一个 Basket 的对象获得的就是 Hashtable 了。

但是需要注意的是,由于所有的子类(Basket)的对象实例共享同一个原型对象(Hashtable),因此在父类对象的构造函数中只能保存对所有子类对象均相同的实例变量。对每个子类不同的实例变量必须放在子类的的构造函数中。很多时候父类对象没有任何自己的实例变量,而只有一些方法,操作的是子类对象的实例变量。

2、JavaScript 中变量的作用域
java代码: 

var v = "aaa";
function func() {
    alert(v);
    ...
    var v = "bbb";
}


alert 出来的是什么?你肯定会说是 "aaa",错,alert 出来的是 "undefined"。为什么?
因为 JavaScript 为了简化处理,变量实际上只有两种作用域,全局变量和函数的内部变量。你在函数内部任何一个地方定义的变量其作用域都是整个函数体。而在 alert 的时候函数的内部变量 v 已经定义了,并且覆盖掉了同名的全局变量 的定义,只是还没有被初始化,所以 alert 出来的是 "undefined"。

3、undefined 和 null
有些开发人员误以为在 JavaScript 中,
return;
返回的就是 null,也就是
return null;

这是一个误解,在 JavaScript 中,
return;
返回的是 undefined,而不是 null。这两个值是有区别的,请看《JavaScritp 权威指南》的相关内容。最好明确地写为:
return null;

这个问题同样在传递参数时候也会出现,例如:
java代码: 

function func(v1, v2) {
    alert(v2);
}
func(1);


alert 显示 v2 的值是 undefined。

虽然在 JavaScript 中:
undefined == null;
得到的结果是 true,将一个 typeof 为 "undefined" 的标识符与 null 做等值比较结果也是 true,似乎这两个值可以混用。但是为了理解的清晰,最好还是把这两个值区分开。

还有一个需要注意的是在 SP2 以前版本的 IE5 中,不能直接拿 undefined 与其它值比较,例如:
java代码: 

if(v2 == undefined)  {
    ...
}


在 SP3 以上版本的 IE5、IE6 都没问题,但是在 SP2 版本前的 IE5 中无法执行。必须要写成:
java代码: 

if(typeof v2 == "undefined")  {
    ...
}
4、当你为一个类添加一个方法时,你经常这样写:
java代码: 

ClassName.prototype.f1 = function () {
    ...
}


你可能想当然地认为 f1 就是这个方法的名称。你想错了,f1 只是这个类的对象的一个普通属性而已,它的值可以是任何类型。这个方法是匿名的,在全局名字空间中并没有它的标识符。如果想在全局名字空间获得一个标识符,你应该采用如下两种方式:
java代码: 

function func1 () {
    ...
}
ClassName.prototype.f1 = func1;


或者
java代码: 

ClassName.prototype.f1 = function func1 () {
    ...
}


这样做的好处是你现在可以在多个类中重用相同的方法(可能性似乎很小,是吧?)。
我这里还是按照面向对象的习惯叫做方法。一般在 JS 中我把类中的 function 称做方法,而把全局范围的 function 称做函数。

5、重载父类的方法后如何调用父类的方法?
你现在已经知道 JS 完全可以实现继承了,当然也可以实现重载,否则还能叫面向对象语言吗?比如在父类 BaseClass 中有一个 f1 的方法,子类 SubClass 要重载这个方法,只需要这样写:

java代码: 

SubClass.prototype.f1 = new function () {
    ...
}


且慢,如果我还想调用父类的方法怎么办呢?不必担心,
java代码: 

SubClass.prototype.f1 = new function () {
    BaseClass.prototype.f1.apply(this, arguments);
    ...
}


这里加的一句就是调用父类的 f1 方法。apply 换成 call 也是可以的。
不过 JS 因为函数参数数量是可变的,所以它并不会把
function f1 (arg1, arg2, arg3)

function f1 ()
看做是两个函数,它会认为它们就是一个函数(小子,换了个马甲就以为我认不出你了?),后面出现的定义会覆盖前面的定义。所以即使你改变子类方法的签名,它仍然认为是重载了父类同名的方法。

那么如果我还想调用父类的构造函数怎么办呢?这样做:
java代码: 

function SubClass (arg1, arg2) {
    BaseClass.call(this, arg1, arg2);
    ...
}

6、JavaScript 开发如何做自动测试?
JavaScript 也是可以做自动测试的。xUnit 框架在 JS 领域的嫡系传人是 JsUnit(http://jsunit.),基本上就是 JUnit 的 JS 版,连例子都是从 JUnit 的例子移植过来的。
如何用 TDD 方式做 JS 开发?这个话题可就大了,足够说上几天的,以后我会另开主题讨论这个问题。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多