读Ext之二(实用方法)
上篇看到Ext.extend,接着往下看。
Ext.namespace,用来管理Ext库命名空间的方法
1 2 3 4 5 6 7 8 9 10 11 | namespace : function (){ var o, d; Ext.each(arguments, function (v) { d = v.split( "." ); o = window[d[0]] = window[d[0]] || {}; Ext.each(d.slice(1), function (v2){ o = o[v2] = o[v2] || {}; }); }); return o; }, |
多数情况下会这么使用
1 | Ext.ns( "Ext.util" , "Ext.lib" , "Ext.data" ); |
Ext.ns是Ext.namespace的简写,这时会为全局的Ext变量挂上util,lib,data属性,Ext.util,Ext.lib,Ext.data默认都是空的对象。当然也可以非Ext开头的命名空间。
Ext.namespace内部使用了Ext.each,顺藤摸瓜
1 2 3 4 5 6 7 8 9 10 11 12 13 | each : function (array, fn, scope){ if (Ext.isEmpty(array, true )){ return ; } if (!Ext.isIterable(array) || Ext.isPrimitive(array)){ array = [array]; } for ( var i = 0, len = array.length; i < len; i++){ if (fn.call(scope || array[i], array[i], i, array) === false ){ return i; }; } }, |
首先判断第一个参数array是否为数组,如果为空直接返回。接着判断array是否可迭代,对于数组、NodeList、 HTMLCollection都是可迭代的,即返回true。不可迭代的,如基本类型的字符串,数字等会将其包装成数组。接着就是for循环,回调函数 fn,fn的执行上下文scope,scope如果没有传默认为array[i],即在fn内使用this取到集合的每一个元素。fn的第一个参数为集合 元素,第二个参数i为索引,第三个参数为被迭代元素自身。
最后还有个技巧,可以在fn内使用某个条件为false如 return i=3 来终止迭代,这时候会返回迭代最后一次的索引i。
可以看到 Ext.each 的用法与 JQuery.each 类似,不同之处在于Ext.each的第三个参数可以指定回调函数的执行上下文,jQuery.each 的第三个参数仅供库内部使用。
Ext.each中使用了Ext.isEmpty方法,
1 2 3 | isEmpty : function (v, allowBlank){ return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false ); }, |
Ext.isEmpty中有句(Ext.isArray(v) && !v.length),这里使用逻辑非运算符而没有使用==,如(Ext.isArray(v) && v.length==0)。即当v是数组时还要检测数组是否为空,如length为4,则!v.length就为false了。即数组不为空。
在看Ext.toArray方法,也是一个匿名函数自执行,执行后返回的function才是真正的Ext.toArray
1 2 3 4 5 6 7 8 9 10 11 12 13 | toArray : function (){ return isIE ? function (a, i, j, res){ res = []; for ( var x = 0, len = a.length; x < len; x++) { res.push(a[x]); } return res.slice(i || 0, j || res.length); } : function (a, i, j){ return Array.prototype.slice.call(a, i || 0, j || a.length); } }(), |
可以看到实现时对浏览器进行了判断,IE使用for循环的遍历 伪数组 ,将其push到res中。非IE浏览器则使用Array.prototype.slice。
IE中为何不能使用Array.prototype.slice呢,对于NodeList等并非一个JavaScript object。会抛异常。怿飞 总结过。
然而,随着IE9的发布,其已将javascript引擎内置在浏览器中,见图
IE9 中Array.prototype.slice.call(NodeList) 已经不再抛异常了,可以使用其将NodeList等转换为数组。因此Ext.isIE这个条件改为 Ext.isIE6||Ext.isIE7||Ext.isIE8 则较为合理了。之前DOM的错误实现也部分修复了,相关 Blog 。
Ext.iterate方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | iterate : function (obj, fn, scope){ if (Ext.isEmpty(obj)){ return ; } if (Ext.isIterable(obj)){ Ext.each(obj, fn, scope); return ; } else if (Ext.isObject(obj)){ for ( var prop in obj){ if (obj.hasOwnProperty(prop)){ if (fn.call(scope || obj, prop, obj[prop], obj) === false ){ return ; }; } } } }, |
这是一个通用迭代器,可以迭代数组,也可以是对象。当为迭代数组/伪数组 时其实是调用上面提到的 Ext.each。参数及使用方式也与 Ext.each 类似。
Ext.urlEncode,该方法用来将js对象序列化成查询字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | urlEncode : function (o, pre){ var empty, buf = [], e = encodeURIComponent; Ext.iterate(o, function (key, item){ empty = Ext.isEmpty(item); Ext.each(empty ? key : item, function (val){ buf.push( '&' , e(key), '=' , (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '' ) : e(val)) : '' ); }); }); if (!pre){ buf.shift(); pre = '' ; } return pre + buf.join( '' ); }, |
里面使用了简写的 e = encodeURIComponent, encodeURIComponent 可以这么写,其是核心js对象,document.getElementById 等BOM对象则不能这么简写。
Ext.urlDecode 则是将查询字符串转换成js对象。
Ext.urlAppend 添加字符串到查询url。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端