开篇:
用Extjs开发了3年半有余,现在项目转型至偏互联网产品半年有余,将js转型至了jquery系列,想来需要博客下Extjs的一些总结和记录,同时也为了温故而知新。
主要使用的是Extjs3.4这个版本,4.0之后的版本用过些许,主要是国内的浏览器的繁杂以及xp系统的更替实在够缓慢,4.0之后在老版本浏览器上加载速度不尽如人意。
下面的介绍就都基于自己最最熟悉的3.4版本。
既然是开篇,介绍一些通用,而又被广大extjs开发者们在初期不容易发现和运用的知识,也是本人觉得一个js库比较精华的部分,就是对于例如array function等的扩展函数。今天来看看function的扩展。
function扩展:
API中可以看到Extjs对function的扩展,有五个:createCallback
createDelegate
createInterceptor
createSequence
defer .
1. createCallback
官方说明: Creates a callback that passes arguments[0], arguments[1], arguments[2], ...Call directly on any function. Example: myFunction.createCallback(arg1, arg2)Will create a function that is bound to those 2 args. If a specific scope is required in thecallback, use createDelegate instead. The function returned by createCallback alwaysexecutes in the window scope.作用: 创建一个函数的绑定参数的函数返回,小心的是该函数的指定作用域this指向的是window这个全局范围,如果需要指定this,可以使用createDelegate替代。 例子:
var sayHi = function(name){ alert('Hi, ' + name); } // clicking the button alerts "Hi, Fred" new Ext.Button({ text: 'Say Hi', renderTo: Ext.getBody(), handler: sayHi.createCallback('Fred') });
例子中通过extjs创建的button的点击后直接就 默认好了参数fred。
源码分析:createCallback : function(/*args...*/){ // make args available, in function below var args = arguments, method = this; return function() { return method.apply(window, args); }; },
直接apply了window对象2. createDelegate
Creates a delegate (callback) that sets the scope to obj.Call directly on any function.官方说明:
Example:this.myFunction.createDelegate(this, [arg1, arg2])
Will create a function that is automatically scoped to obj so that the this variable inside thecallback points to obj.作用: 创建一个函数的绑定参数的函数返回,作用和上一个类似,额外可以传递作用对象,即函数内的this指向。 例子:
var sayHi = function(name){ // Note this use of "this.text" here. This function expects to // execute within a scope that contains a text property. In this // example, the "this" variable is pointing to the btn object that // was passed in createDelegate below. alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.'); } var btn = new Ext.Button({ text: 'Say Hi', renderTo: Ext.getBody() }); // This callback will execute in the scope of the // button instance. Clicking the button alerts // "Hi, Fred. You clicked the "Say Hi" button." btn.on('click', sayHi.createDelegate(btn, ['Fred']));
例子中将this指向btn 于是可以获取this.text
源码分析: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); // copy arguments first var applyArgs = [appendArgs, 0].concat(args); // create method call params Array.prototype.splice.apply(callArgs, applyArgs); // splice them in } return method.apply(obj || window, callArgs); }; },
源码对参数做了一些处理,然后将逻辑包装在一个函数内返回出去。3. createInterceptor
Creates an interceptor function. The passed function is called before the original one. If it returns false,the original one is not called.官方说明:
The resulting function returns the results of the original function.The passed function is called with the parameters of the original function作用: 等于在原函数前先执行个函数,创建一个插入函数,在插入函数中返回false则原函数不会调用,否则新的生成的函数就先执行插入函数再执行原函数,返回原函数的返回。 例子:
var sayHi = function(name){ alert('Hi, ' + name); } sayHi('Fred'); // alerts "Hi, Fred" // create a new function that validates input without // directly modifying the original function: var sayHiToFriend = sayHi.createInterceptor(function(name){ return name == 'Brian'; }); sayHiToFriend('Fred'); // no alert sayHiToFriend('Brian'); // alerts "Hi, Brian"
例子中传入fred,插入的函数判断false则不执行原函数。源码分析:
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; }; }, <span style="color:#FF0000;">额外可以看到false的时候return的是null</span>
4. createSequence
Create a combined function call sequence of the original function + the passed function.官方说明:
The resulting function returns the results of the original function.The passed fcn is called with the parameters of the original function.作用: 等于在原函数后增加一个函数执行。仍然返回原函数的结果 例子:
var sayHi = function(name){ alert('Hi, ' + name); } sayHi('Fred'); // alerts "Hi, Fred" var sayGoodbye = sayHi.createSequence(function(name){ alert('Bye, ' + name); }); sayGoodbye('Fred'); // both alerts show
源码分析:
createSequence : function(fcn, scope){
var method = this;
return (typeof fcn != 'function') ?
this :
function(){
var retval = method.apply(this || window, arguments);
fcn.apply(scope || this || window, arguments);
return retval;
};
}
包装一个函数先调用原函数,保存返回,再调用新函数,然后返回保存的值。5. defer
Calls this function after the number of millseconds specified, optionally in a specific scope.官方说明:
作用:
在数毫秒后执行函数,其实就是简单的delaytask,或者方便的settimeout版本
例子:var sayHi = function(name){ alert('Hi, ' + name); } // executes immediately: sayHi('Fred'); // executes after 2 seconds: sayHi.defer(2000, this, ['Fred']); // this syntax is sometimes useful for deferring // execution of an anonymous function: (function(){ alert('Anonymous'); }).defer(100);
源码分析:
defer : function(millis, obj, args, appendArgs){
var fn = this.createDelegate(obj, args, appendArgs);
if(millis > 0){
return setTimeout(fn, millis);
}
fn();
return 0;
}
可以看到简单组合下 调用settimeout
总结下:几个函数封装其实都只有不多行代码,但是实用程度却很高,我比较常用createdelegate defer
注意下源码分布在不同的src core ext.js中4个 src core ext-more.js中1个createSequence
而在Ext对象上和Ext.util.Functions上也有对应的这五个方法,使用方式稍微不同而已,作用一样。
现在已经不使用Extjs了 ,还是喜欢这几个函数的 可以将此部分源码适当移植使用。
现在在使用underscore中的一些方法,提供的更多一些,
比如throttle其实就是个前台界面不错的封装,类似jquerydatatable也有throttle的封装,避免频繁调用时候有奇效
扯远了,止于此吧。既然开了系列的头,后面闲暇会零散跟上些extjs里面的其他不错的使用介绍。