jQuery1.2 参考(CHM 格式)下载December 16, 2007

感谢 awflasher 兄弟的 分享 ,这份 CHM 文档正是我目前开发所必须的。我对 awflasher 兄弟对于 jQuery 见解非常的赞同(详见 他的 Blog ):

我认为,原型开发者(Prototype Developer)肯定更加喜爱 jQuery 这套框架,
没有 Yui-Ext 的庞杂,没有 Prototype(框架)的 OOP 语法。jQuery 的「哲
学」(philosophy,或者叫「理念」吧)无不映射着一种「简单、朴实」之美:
Find things, do stuff(我姑且理解为「物尽其用」)

希望大家能认识 jQuery 这个优秀的 Javascript 框架。我本人也写过 一些用 jQuery 做的小东西 ,同时再推荐下我以前转自某博客的一篇 jQuery 相关的 文档 ,非常的有用。

废话不多说,这里是 Zip 格式 打包下载

更新 JavaScript 数组的 uniq 方法December 11, 2007

上次写的一篇《 JavaScript 数组的 uniq 方法 》,发现代码的问题还是存在。比如如果数组内有 undefined 元素就无法过滤等。

昨天看见 Lazy 兄弟重新更新了函数,现在他是这样子写的:

Array.prototype.uniq = function() {
    var resultArr = [],
        returnArr = [],
        origLen = this.length,
        resultLen;

    function include(arr, value) {
        for (var i = 0, n = arr.length; i < n; ++i){
            if (arr[i] === value) {
                return true;
            }
        }

        return false;
    }

    resultArr.push(this[0]);
    for (var i = 1; i < origLen; ++i) {
        if (include(resultArr, this[i])) {
            returnArr.push(this[i]);
        } else {
            resultArr.push(this[i]);
        }
    }

    resultLen = resultArr.length;
    this.length = resultLen;
    for (var i = 0; i < resultLen; ++i){
        this[i] = resultArr[i];
    }

    return returnArr;
}

按照他的说法:「这种解法在整个过程对原有数组的改变只有两次,效率比其他两种高了2个数量级左右!」,我实测了下此函数的效率,的确如此( 测试连接点这里 )。

我也重新编写和更新了我的函数,现在看起来是这个样子的:

Array.prototype.uniq = function() {
    var tmp    = new Array;
    var length = this.length;

    for(var i = 0; i < length; i++) {
        var push = true;
        for(var j = i + 1; j < length; j++) {
            if(this[j] === this[i]) {
                push = false;
                break;
            }
        }

        if(push) {
            tmp.push(this[i])
        }
    }

    this.length = tmp.length;
    for (var i = 0; i < tmp.length; i++) {
        this[i] = tmp[i];
    }

    return tmp;
}

由同一个页面测试所得,效率还是 Lazy 兄弟的稍许快些。经过一点思考以后,我有了些一点点我的心得:

  1. 我的函数 for 嵌套可以用一个函数独立(就如 Lazy 兄弟的 include 函数一样)。在上述的情况下,调用函数会比循环判断效率要高一些。
  2. 数组的循环读写操作在数据量大的情况下应格外的注意效率问题

Lazy 兄弟的结论:

对数组的改变开销巨大,如果可能,尽量在不改变原有数组的情况下进行操作。
如最终需要改变数组自身,可将结果赋予原有数组来操作。另外,对于 length
的计算,似乎效率并未受其影响。

Lazy 兄弟的 resultArr 数组按照他这样的写法就可以保存同样的值,在这里赞一个(虽然我的函数经过一点小的修改也可以实现)。感兴趣的朋友可以去 Lazy 的页面 去看看。

最后,推荐阅读一下王元涛兄弟的 JavaScript 数组的 uniq 方法 ,万分感谢。

JavaScript 数组的 uniq 方法December 8, 2007

请给 Array 本地对象增加一个原型方法,它的用途是删除数组条目中重复的条目(可能有多个),
返回值是一个包含被删除的重复条目的新数组。

Lazy 兄弟给出了它自己的解法,而我个人认为这样的解法算法上还有需要改进的地方。正如回复中 fdcn 兄弟所说,如果将数组:[1, 2, 3, 3, null, null, 2] 带入 Lazy 兄的函数,那么按照循环判断条件就会退出,导致数组之后的元素就不会判断了。

下面给出我的解决方法:

Array.prototype.uniq = function(){
    var tmp    = new Array;
    var length = this.length;

    for(var i = 0; i < length; i++) {
        var push = true;
        var item = this[i];

        for(var j = i + 1; j < length; j++) {
            if(this[j] == item) {
                push = false;
            }
        }

        if(push == true) {
            tmp.push(item)
        }
    }

    return tmp;
}

Lazy 兄弟也说到每次循环都将重新计算 length 会有开销,那么我将 legth 定义为一个常量,原数组为「只读」,那么 length 相对不变,就不要重复计算了。然后再定义一个数组往里面扔「垃圾」。

数组嵌套循环并不遍历原数组的每一个元素,仅判断剩余没有出现的值。最后获得一个是否 push 的布尔值,然后跳出循环判断是否插入。

最后,欢迎大家交流讨论。


更新,和 Lazy 兄弟讨论后,我发现此函数写得也不是非常的严谨。因为它没有修改原函数的元素,于是我又作了如下的修改:

Array.prototype.uniq = function(){
    var tmp    = new Array;
    var length = this.length;

    for(var i = 0; i < length; i++) {
        var push = true;
        var item = this[i];

        for(var j = i + 1; j < length; j++) {
            if(this[j] == item) {
                push = false;
            }
        }

        if(push) {
            tmp.push(item)
        }
    }

    this.length = tmp.length;
    for (var i = 0; i < tmp.length; i++) {
        this[i] = tmp[i];
    }

    return tmp;
}

但这样又出现了一个问题,就是重复赋值会不会增加时间长度。因为我是在取出来了以后再做一次循环重新赋值给原数组。按照我这样的写法实现已经没有问题,但是效率可能需要进一步的调整。

继续改进ing


不好意思,再次更新。根据上述的问题,我重新优化了下算法,并将 Lazy 兄弟的「思想」加了进来,于是就有如下的代码了:

Array.prototype.uniq = function(){
    var i = 0, j = 0;
    while (undefined !== this[i]){
        j = i + 1;
        while(undefined !== this[j]){
            if (this[i] === this[j]) {
               this.splice(j, 1);
            }
            ++j;
        }

        ++i;
    }

    return this;
}

是的,非常的短,不过却能完成题目所给的要求了。这个相对我以前的函数,有一个好处就是没有生成另外的一个数组。而且也没有像第二个函数这样的重复赋值。

嗯,我想目前这个样子已经能满足题目的要求了。

Yahoo 统计