`

《仔仔细细分析Ext》 脚本,你的效率到底损失在哪里?:Ext对Array对象的扩展

阅读更多

导言

         差不多所有的 js 库都会对原生的 js DOM 模型进行封装和扩展, jQuery prototype Ext 都有类似做法。

         由于这些原生对象的相关方法注定会被大量地调用,对它们扩展得好与不好会直接关系到整个类库整体的性能。

         经常看到有人说 Ext 的执行效率低下,笔者有时也有这种感觉,点个鼠标好像要延迟一下才有反应。但是说话得要有根据不是,不知道慢在哪里也不能跟着瞎起哄。(当然,也免得文章发出来被别人拍板砖,已经被拍过几次,汗啊 )。

         前一部分文章说了一下怎么用 VML 直接在网页上绘图,并且封装了一个小工具。这一部分的内容就先来看一下 Ext js 的原生对象是如何封装和扩展的。

 

 

概览

        

 

         从截图可以看到,在 Ext.js 这个文件中, Ext Function String Number Array Date 。五个原生对象进行了扩展。这一篇先来分析一下对 Array 对象的扩展,并提出一个小小的疑惑。

 

Array 对象

         js 的原生 Array 对象包含一个 length 属性和 12 个方法,简表如下:

         concat() :添加元素

         join() :将数组中的元素连接成一个字符串并返回

         pop() :弹出最后一个元素

         push(): 把一个元素加到数组最后

         reverse(): 颠倒顺序

         shift(): 移除第一个元素

         slice() :返回子数组

         splice(): 插入、删除或替换一个元素

         toLocaleString(): 把数组转换成一个本地化的字符串

         toString() :把数组转化成一个字符串

         unshift() :在数组头部插入一个字符串

 

         以上引自《 JavaScript 权威指南 第五版》,加粗部分是自己对照英文版的的翻译,原来的翻译是“把数组转换成一个局部字符串 ”,意思非常模糊,让人搞不懂。顺便再罗嗦一下,第五版的翻译不知道是干什么吃的,很多的东西不翻译或者直译,漏洞百出,建议想买这本书的人不要买这个版本。

        

Ext.js 里给 Array 对象扩展了两个方法,代码如下(注释已经翻译成中文):

Ext.applyIf(Array.prototype, {

    /**

     * 查找数组中是否存在指定的对象

     * @param {Object} 需要查找的对象(的引用)

     * @return {Number} 对象在数组中的位置下标 ( 如果不存在该对象,返回 -1)

     */

    indexOf : function(o){

             // 注意这里:是简单的线性查找,拿数组中的元素一个一个地去对比。

       for (var i = 0, len = this.length; i < len; i++){

               if(this[i] == o) return i;

       }

            return -1;

    },

        

    /**

     * 从数组中删除指定的元素,如果该元素不存在,则什么事情都不做。

     * @param {Object} o 需要删除对象的引用

     * @return {Array} 返回删除后的数组

     */

    remove : function(o){

       var index = this.indexOf(o);

       if(index != -1){

           this.splice(index, 1);

       }

       return this;

    }

});

 

在注释里面加注意的地方说到 indexOf() 方法的查找问题,可以看到,这里的 indexOf() 使用的是简单的线性查找, remove() 方法调用了这个 indexOf() 方法来查找对象在数组中的位置。这个地方的效率很低,也就是说,如果我们往一个数组里面保存了很多的对象,然后在另外的地方频繁调用数组的 indexOf() 或者 remove() 方法的时候,速度就会比较慢。所以有人老说 Ext 存在效率问题,我想,这个所谓的“效率问题”不是哪一处地方造就的,而是由诸多效率差的小细节积累而成的,假如我们实在没有办法去改变什么,那么至少要注意到这些地方,避免陷阱,这是这篇文的主旨所在。

由于线性查找效率是 O(n) ,所以,在数据量稍大的时候,需要寻找替代 Array 的办法。有很多文章说过关于 Array 的这个问题,包括《权威指南》,办法是模拟一个 Hash 表。基本的思路如下:

var mp={};

         mp['key1']={name:'damoqiongqiu',age:'25',QQ:'88403922'};

         mp['key2']={name:'damoqiongqiu',age:'26',QQ:'88403922'};

         alert(mp.key2.name);     

         这样处理,可以提升查找效率,效率可能接进 O(1) 。(顺便说一句,效率只能接进是 O(1) ,因为 js 内部通过这个字符串型的 key 去找到 value 也是需要花时间的,即使是通过类似Java或C++的Hash算法,也是需要通过key来算HashCode的不是?通过HashCode找到对应的Hash桶之后还是一个线性查找。)

        

         《指南》里面还有提到一种伪数组:

         var a={}

         while(i<10){

                  a[i]=i*I;

                   i++

         }

         a.length=i;

        

         如果情况比较好,事先知道插入的元素是有序的就可以使用其它的查找算法,像二分查找之类的,这样的情况估计不容易遇到,除非上天恩赐 J ,否则还讨论个什么劲?

        

         当然,有些情况必须用到数组,除此没有办法,那还有什么好说的,用呗!但是,在确确实实对效率有很多要求的地方,需要考虑类似的变通方法。

 

一个疑惑:

经常看到有人问, js 里面的 == === 有什么区别,翻了一下书,大概的意思是:

=== 是比较两个值是不是完全相等。

而如果用 == 来比较,假如两个值是同一类型,就用 === 比较它们是否等同。否则如果两个值是以下组合时,将非 Number 型强转成 Nunber 再来比较。

String Number

Number Boolean

也就是说, ”1”==true 是正确的, 1==true 也是正确的,如此这般。

如果一个值是对象,另一个值是 String 时,将对象转成 String ,再来比较这两个 String 是不是相等。

 

         OK ,有了上面的简单解释,我们来测试一下 Ext Array indexOf() 方法。

         首先来个简单的:

         Ext.onReady(function(){

         // 基础语义测试

         var test="1";

         alert(test==true);

})

没有问题,出来一个 true

 

再来个稍微复杂点的,先向数组里面插入 1000 个对象,然后在第六个元素放一个布尔型的 true 值,然后自己来遍历数组,看看有没有元素和字符型的 ’1’ 相等:

Ext.onReady(function(){

         // 自定义数组测试

         var test="1";

         var arr=[];

         for(var i=0;i<1000;i++){

                   var temp=(i==5)?true:{id:i};

                   arr.push(temp)

         }

         for (var i = 0, len = arr.length; i < len; i++){

             if(arr[i] ==test){

                      alert(i);

                            break;

             }

    }

})

好,没有问题,找到了第六个元素。

 

来测 Array indexOf() 方法,从 Ext 的源码里面可以看到, Array indexOf() 方法和我们上面自己遍历的方法是一样的,但是,神奇的事情发生了,看代码:

Ext.onReady(function(){

         // 自定义数组测试

         var test="1";

         var arr=[];

         for(var i=0;i<1000;i++){

                   var temp=(i==5)?true:{id:i};

                   arr.push(temp)

         }

    // 测试 Ext 封装 Array indexOf() 方法

         alert(arr.indexOf(test));

})

按道理来说,这里也应该能够弹出来元素的位置,但是,结果是,没有找到这个元素。。。可视,这是为什么呢?期待牛人给出解释,不甚感谢!


 


这个问题已解决,多谢zbm2001的解释,我自己又测试了一下,只有FireFox实现了Array原生的indexOf()方法,而IE、Safari、Opera都没有原生实现。Ext在扩展的时候用的是applyIf()方法,所以在存在原生实现的时候不会拿Ext的实现去覆盖。

分享到:
评论

相关推荐

    cgi程序机器人大战美工版

    作人 :?聊仔 安??明: 1、修改 config.cgi 中的相关设定。 2、在cgi-bin目?外存放images中的img1和img2,??目?路???於config.cgi中,否?不能正常?示。 3、?於cgi的安?和架?不在本文中探?。 4、任何bug和??...

    Magic Partition Recovery

    注?信息: 用?名:大眼仔~旭(Anan) 注??:7069-3890-1986-9697 注??:3647-7903-0568-7523 注??:5497-5001-9890-1336 Magic NTFS Recovery

    Magic_NTFS_Recovery

    Magic Partition Recovery 注?信息: 用?名:大眼仔~旭(Anan) 注??:9419-0906-9494-0679 注??:8642-4141-6687-0186 注??:5157-3585-0291-2592

    蓝色简洁的响应式布局bootstrap后台系统管理模板html源码源码下载HTML源码H5整站.zip

    总的来说,这个模板包含了一套完整的后台管理界面,使用了流行的Bootstrap框架,提供了响应式设计,确保在各种设备上都能良好显示。开发者可以快速搭建后台管理系统,通过修改HTML、CSS和JavaScript文件来定制自己的...

    绿色实用的后台管理ui框架源码下载HTML源码H5整站.zip

    UI框架是开发者用来快速设计和开发用户界面的一种工具,通常包括预定义的样式、组件和交互模式,能够帮助开发者节省时间和提高工作效率。 在提供的文件名列表中,我们可以看到该框架包含以下主要部分: 1. `??????...

    蓝色的医院oa后台模板html源码源码下载HTML源码H5整站.zip

    OA系统是为了提高医疗机构内部工作效率,整合资源而设计的信息管理系统。 描述部分与标题基本一致,强调这是一个HTML源码,适用于H5(第五代超文本标记语言)的整站构建。这意味着模板遵循现代网页开发标准,支持...

    蓝色精美的booststrap响应式后台模板源码下载HTML源码H5整站.zip

    【标题】"蓝色精美的booststrap响应式后台模板源码下载HTML源码H5整站.zip" 提供的是一款基于...在实际应用中,开发者还可以根据需求自定义CSS皮肤,调整布局,或者扩展JavaScript功能,以满足特定项目的需求。

    蓝色的oa办公系统后台管理界面模板源码源码下载HTML源码H5整站.zip

    \assets\js\date-time\:JavaScript文件夹,包含项目所需的脚本文件,其中"date-time"可能是一个专门处理日期和时间的子目录。 综合以上信息,我们可以得知这个OA办公系统后台管理界面模板包含了一个完整的前端结构...

    自动化测试的脚本 自动执行浏览器的操作

    自动化测试脚本能够显著提高测试效率,减少手动测试的工作量,并确保产品在不同环境下的稳定性。这里我们将深入探讨“自动化测试的脚本自动执行浏览器的操作”,主要关注使用Selenium这一强大的工具。 Selenium 是...

    ext-4.2.0-beta

    EXTJS 4.2.0 Beta 版本是EXTJS框架的一个重要里程碑,它在原有的4.1.x系列基础上引入了新的特性和改进。EXTJS是一个强大的JavaScript库,专为构建交互式、数据驱动的Web应用程序而设计。4.2.0测试版尤其值得关注,...

    网络协议分析与仿真课程设计

    用脚本分析大流量数据(建议用perl); 内容:Web流量分析 搭建Web服务器和DNS服务器,要求Web服务器IP地址为“xx.xx.xx.学号的后三位”,要求DNS服务器IP地址为“xx.xx. 学号的后三位. xx”;用Web服务器、DNS...

    [检测统计]牛仔IIS日志蜘蛛爬行记录分析器 v1.1_iis_rz.zip

    【牛仔IIS日志蜘蛛爬行记录分析器 v1.1】是一款专门针对IIS(Internet Information Services)服务器日志进行分析的工具,主要用于帮助网站管理员了解搜索引擎蜘蛛的爬行行为,从而优化网站的SEO策略。IIS是微软公司...

    数据可视化大屏展示系统HTML模板源码 大数据大屏展示源码 VUE.zip

    在实际应用中,数据可视化大屏通常会包含多个模块,如实时数据监控、趋势分析、预警提示等,每个模块都由独立的Vue组件构成,这样既能保证代码的清晰性,又能提高开发效率。ECharts提供的丰富的图表选项和交互能力,...

    扩展ACL的应用实例及解析.docx

    "扩展ACL的应用实例及解析" 扩展ACL(Access Control List,访问控制列表)是一种网络安全机制,用于控制网络流量,保护网络资源。扩展ACL是标准ACL的升级版本,具有更多的灵活性和功能性。 扩展ACL的分类: 1. ...

    安服仔必备--FofaCollector(fofa采集脚本)2022最新版

    安全工作者在业务中经常会用到fofa搜集甲方资产(子域名,旁站,c段等),该脚本使用python3编写,分为API版(最多只能获取1w条数据)和爬虫版(有多少数据就能获取多少数据,需要cookie),且都为命令行参数形式。...

    EF扩展方法BulkInsert(批量添加)

    在.NET开发中,Entity Framework(简称EF)是一个强大的对象关系映射(ORM)框架,它允许开发者使用面向对象的编程语言来操作数据库。在处理大量数据插入时,传统的逐条插入方式可能会导致性能低下,此时我们可以...

    蓝色精美简洁MUI后台管理模板源码下载HTML源码H5整站.zip

    - 在`js`目录下的脚本文件中添加或修改逻辑,实现后台管理的各种功能,如数据检索、编辑保存、权限控制等。 - 根据业务需求,调整或复制`list.html`、`column.html`等HTML模板,创建新的视图页面。 - 将图片资源替换...

    明仔PHP面向对象(六日通)教程.rar

    通过《明仔PHP面向对象(六日通)教程》的学习,你不仅能够掌握PHP面向对象的基本语法,还能了解如何在实际项目中应用这些概念,提升你的编程技能。同时,教程中的"说明.htm"文件可能会提供课程的使用指南、学习路径...

Global site tag (gtag.js) - Google Analytics