Ext为javascript的一些对象进行了扩展,主要有String、Array和Function,以下只介绍Ext.js中提到的方法,其他的后续再介绍
Ext为String扩展了方法 format,该方法为String的静态方法(类方法),可以把字符串中特殊写法({0},{1})用指定的变量替换
-
-
-
-
-
-
- format : function(format){
- var args = Ext.toArray(arguments, 1);
- return format.replace(/\{(\d+)\}/g, function(m, i){
- return args[i];
- });
- }
Ext为Array扩展了方法 indexOf 和remove,这两个方法分别实现了索引和根据子元素删除对应的该元素
- Ext.applyIf(Array.prototype, {
-
-
-
-
-
-
- indexOf : function(o, from){
- var len = this.length;
- from = from || 0;
- from += (from < 0) ? len : 0;
- for (; from < len; ++from){
- if(this[from] === o){
- return from;
- }
- }
- return -1;
- },
-
-
-
-
-
-
- remove : function(o){
- var index = this.indexOf(o);
- if(index != -1){
- this.splice(index, 1);
- }
- return this;
- }
- });
编者在实际开发中经常会用到以下两个方法,也很实用
-
-
-
-
-
-
- insert : function (index,o){
- if(index <= 0){
- return this.unshift(o);
- }
- if(index >= this.length){
- return this.push(o);
- }
- var sub = this.slice(index, this.length);
- this.length = index;
- this.push(o);
- for(var i = 0; i < sub.length; i++){
- this.push(sub[i]);
- }
- return this;
- },
-
-
-
-
-
-
- removeAt : function(index){
- if(index != -1){
- this.splice(index, 1);
- }
- return this;
- }
以下扩展String方法也很有用
- Ext.applyIf(String,{
-
-
-
-
-
-
-
-
- humpToConnector : function(str, conj){
-
- var index = str.search(/[A-Z]/);
- if (index >= 0) {
- var c = str.charAt(index);
- return String.humpToConnector(str.substring(0, index) + conj
- + c.toLowerCase() + str.substring(index + 1), conj);
- } else {
- return str;
- }
- }
- });
Ext对Function的扩展
createInterceptor方法
- createInterceptor : function(fcn, scope){
- var method = this;
- return !Ext.isFunction(fcn) ?
- this :
- function() {
- var me = this,
- args = arguments;
- fcn.target = me;
- fcn.method = method;
- return (fcn.apply(scope || me || window, args) !== false) ?
- method.apply(me || window, args) :
- null;
- };
- },
该方法实现了类似拦截器的功能,传递的参数fcn在原函数之前调用。如果fcn的返回值为false,则原函数不会被调用。即函数fcn拦截时,如果fcn返回false,将被拦截,true则执行。以下说明方法中的部分语句。
var method = this,因为是给Function.prototype扩展,因此其prototype上挂的所有的函数,函数内的this都是Function,即函数自身。看下面例子
- Function.prototype.test = function(){
- alert(this);
- };
- function fn(){return 'test';}
- fn.test();
结果输出
function fn() {
return "test";
}
即this就是fn函数本身
!Ext.isFunction(fcn),这个条件表明如果所传参数fcn不是一个function,那么将直接返回this,this即函数自身。或者说这时没有进行任何拦截,原样返回了该函数自身。
当fcn为一个function时,将执行 “:”后的分支,此时给fcn添加了两个属性target,method。target是me,me是this。
此时的this是什么呢?多数情况下是window,但整个function如果作为对象属性存在时,this则是该对象。谁调用了createInterceptor,method就是谁。如:
- function oldFn(){
- alert('test');
- }
- function ret(){
- return false;
- }
- var newFn = oldFn.createInterceptor(ret);
- newFn();
oldFn继承了createInterceptor方法,且调用了它,参数是ret。这时createInterceptor内部的method, fcn.method就是oldFn;me,fcn.target则为window对象。改成如下,me,fcn.target则为obj了
- function oldFn(){
- alert('test');
- }
- function ret(){
- return false;
- }
- var obj = {name:'jack'};
- obj.method = oldFn.createInterceptor(ret);
- obj.method();
(fcn.apply(scope || me || window, args) !== false),所传参数fcn被执行,执行上下文优先是scope,其次是me,最后是window。返回结果不等于false才执行method。method执行上下文先为me,me不存在则是window。
现把官方例子贴出来
- var sayHi = function(name){
- alert('Hi, ' + name);
- }
-
- sayHi('Fred');
-
-
-
- var sayHiToFriend = sayHi.createInterceptor(function(name){
- return name == 'Brian';
- });
-
- sayHiToFriend('Fred');
- sayHiToFriend('Brian');
该例子在createInterceptor中 fcn.apply(scope || me || window, args) 相当于直接执行
function(name){
return name == 'Brian';
}
只是将函数绑定到另外一个对象上(scope || me || window)去运行
method 实际为sayHi
createCallback方法
-
- createCallback : function(){
-
- var args = arguments,
- method = this;
- return function() {
- return method.apply(window, args);
- };
- },
这个方法非常有用,实现简单。返回一个新函数,新函数内执行method,会把外面的参数给传进来。
初学者经常 纠结于给事件handler传参数 。createCallback 解决了给DOM事件handler(监听器)传参问题。
createCallback 不仅用在DOM事件handler上你完全可以自定义事件,设计一套属于自己的 观察者模式 API。即每个类有自己的事件,如 LTMaps ,除了拥有属性,方法还有许多事件,如移动地图(move),缩放地图(zoom)。Ext的众多UI组件也都是这种模式,Ext.Panel 具有afterlayout,close等事件。
在给这些事件添加hanlder,又想传参或许也会用到 createCallback。
createDelegate 方法
-
-
-
-
-
- createDelegate : function(obj, args, appendArgs){
- var method = this;
- return function() {
- var callArgs = args || arguments;
- if (appendArgs === true){
- callArgs = Array.prototype.slice.call(arguments, 0);
- callArgs = callArgs.concat(args);
- }else if (Ext.isNumber(appendArgs)){
- callArgs = Array.prototype.slice.call(arguments, 0);
- var applyArgs = [appendArgs, 0].concat(args);
- Array.prototype.splice.apply(callArgs, applyArgs);
- }
- return method.apply(obj || window, callArgs);
- };
- },
createDelegate 比 createCallback 更强大,除了能解决回调函数传参问题。还能控制:
1, 自定义参数是否覆盖默认参数(如 DOM事件对象 作为handler第一个参数)
2, 自定义参数的位置
内部实现:取自身(var method=this),返回一个新function,该function调用自身(method.apply),同时指定上下文(obj||window)及参数(callArgs)。就这么简单,细节之处在于对参数的控制。
1,只传obj和args时将覆盖回调函数默认参数(DOM事件对象)
- <a href="#" id="aa">SINA</a>
- <script type="text/javascript">
- var aa = document.getElementById('aa');
- function sayName(name){
- alert('hello, ' + name);
- }
- var sayName2 = sayName.createDelegate(aa,['jack']);
- aa.onclick = sayName2;
- </script>
2,三个参数都传,appendArgs为true时,默认参数(DOM事件对象)位置不变(第一个),自定义参数args在最后
- <a href="#" id="aa">SINA</a>
- <script type="text/javascript">
- var aa = document.getElementById('aa');
- function sayName(){
- alert('实际参数长度:' + arguments.length);
- alert('hello, ' + arguments[0]);
- alert('hi, ' + arguments[1]);
- }
- var sayName2 = sayName.createDelegate(aa,['jack'],true);
- aa.onclick = sayName2;
- </script>
3, 三个参数都传,appendArgs为数字时将指定自定义参数的位置
- <a href="#" id="aa">SINA</a>
- <script type="text/javascript">
- var aa = document.getElementById('aa');
- function sayName(name){
- alert('实际参数长度:' + arguments.length);
- alert('hello, ' + arguments[0]);
- alert('hi, '+ arguments[1]);
- alert('hi, '+ arguments[2]);
- }
- var sayName2 = sayName.createDelegate(aa,['jack','lily'],0);
- aa.onclick = sayName2;
- </script>
defer 方法
-
-
-
-
-
-
-
-
- defer : function(millis, obj, args, appendArgs){
- var fn = this.createDelegate(obj, args, appendArgs);
- if(millis > 0){
- return setTimeout(fn, millis);
- }
- fn();
- return 0;
- }