無標題文檔

jQuery 和 Prototype 的 Cheat Sheet

本人一直在「偷懒」 使用 jQuery 框架。同时我也认识到 Prototype 这个 Javascript 框架似乎也不错(不过已经能使用 jQuery 解决问题了,那么就别无所求了)。

无意间看到篇 文章 ,是讲述 Prototype 和 jQuery 两个「阵营」的,作者说的非常的有道理,引用一下:

造成代码风格的这种差异,其实是两个 framework 的开发者不同的代码哲学造成的。
对于 prototype 来说,非常类似 Java 的处理方式:将一系列的功能封装到一个类
之中,比如 Math 类。而对于 jQuery 来说,其哲学理念是将所有的 HTML 节点都
视为一个 Object , 通过调用这个 Object 上面不同的方法向这个 Object 发送不
同的消息,来让 Object 自己实现不同的功能,产生不同的表现。

我个人而言,不管怎么样,这两个 Javascript 框架都是非常优秀的。有兴趣的朋友可以选择自己喜欢的学习之。但我发现原文的两张大图链接由于 某些原因 不能下载,于是我将其做了一个「镜像」方便大家使用。

https://friable.rocks/_/2007_12_20/1745166417.jpg

https://friable.rocks/_/2007_12_20/1366687851.jpg

还是按照传统,在这里可以 ZIP 打包下载 ,或者访问我的 Yupoo 相册 获得。

另,免费出售 MySQL Cheat Sheet 中文版 一张,欲抢从速。

jQuery1.2 参考(CHM 格式)下载

感谢 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 方法

上次写的一篇《 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 方法

请给 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;
}

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

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

Javascript 做的一个小玩具

这是一个 Javascript 编写的,类似于 X 下的 xeyes 的一个小玩具。我是根据 Dynamicdrive.com 上 Kurt Grigg 所编写的 Watching Eyes 整理所得。原始版本可以从 这里 获得。

那么个和原来的代码有什么不同的地方?我主要做了两件事情,一是将其代码整理了一下,以便更容易阅读;二是使用 jQuery 框架减少了许多浏览器检测和样式设置方面的代码。

安装的方法我罗嗦一下,加入两行就可以了。第一行是载入 jQuery 库,接下来就是载入此脚本:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.eye.js"></script>

兼容性方面,我已在 IE6、Firefox、Opera、Safari(Windows 版本)下测试通过。

https://friable.rocks/_/2007_11_21/1195634758.jpg

上图截图为此脚本 Safari for Windows 下的运行情况。

废话话不多说,感兴趣的朋友可以看下 这里的 DEMO ;代码打包下载 在这里

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHub (2) 、 TwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 其实无所谓叫什么名字,作为码农知道取名是件很难的事情。最后想到的这个名字,其实都没啥特别的含义,系统默认的文件名而已。

作为八零后,自认为还仅存点傲娇式的幽默感,以及对平淡生活的追求和向往。 为了免得对号入座和不必要的麻烦,声明本站点所持观点仅代表个人意见,不代表自己所服务公司的立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

文章

项目