Ext.Function = { flexSetter: function(fn) { return function(a, b) { var k, i; if (a === null) { return this; } if (typeof a !== 'string') { for (k in a) { if (a.hasOwnProperty(k)) { fn.call(this, k, a[k]); } } if (Ext.enumerables) { for (i = Ext.enumerables.length; i--;) { k = Ext.enumerables[i]; if (a.hasOwnProperty(k)) { fn.call(this, k, a[k]); } } } } else { fn.call(this, a, b); } return this; }; }, bind: function(fn, scope, args, appendArgs) { var method = fn, applyArgs; 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); applyArgs = [appendArgs, 0].concat(args); Array.prototype.splice.apply(callArgs, applyArgs); } return method.apply(scope || window, callArgs); }; }, pass: function(fn, args, scope) { if (args) { args = Ext.Array.from(args); } return function() { return fn.apply(scope, args.concat(Ext.Array.toArray(arguments))); }; }, alias: function(object, methodName) { return function() { return object[methodName].apply(object, arguments); }; }, createInterceptor: function(origFn, newFn, scope, returnValue) { var method = origFn; if (!Ext.isFunction(newFn)) { return origFn; } else { return function() { var me = this, args = arguments; newFn.target = me; newFn.method = origFn; return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null; }; } }, createDelayed: function(fn, delay, scope, args, appendArgs) { if (scope || args) { fn = Ext.Function.bind(fn, scope, args, appendArgs); } return function() { var me = this; setTimeout(function() { fn.apply(me, arguments); }, delay); }; }, defer: function(fn, millis, obj, args, appendArgs) { fn = Ext.Function.bind(fn, obj, args, appendArgs); if (millis > 0) { return setTimeout(fn, millis); } fn(); return 0; }, createSequence: function(origFn, newFn, scope) { if (!Ext.isFunction(newFn)) { return origFn; } else { return function() { var retval = origFn.apply(this || window, arguments); newFn.apply(scope || this || window, arguments); return retval; }; } }, createBuffered: function(fn, buffer, scope, args) { return function(){ var timerId; return function() { var me = this; if (timerId) { clearInterval(timerId); timerId = null; } timerId = setTimeout(function(){ fn.apply(scope || me, args || arguments); }, buffer); }; }(); }, createThrottled: function(fn, interval, scope) { var lastCallTime, elapsed, lastArgs, timer, execute = function() { fn.apply(scope || this, lastArgs); lastCallTime = new Date().getTime(); }; return function() { elapsed = new Date().getTime() - lastCallTime; lastArgs = arguments; clearTimeout(timer); if (!lastCallTime || (elapsed >= interval)) { execute(); } else { timer = setTimeout(execute, interval - elapsed); } }; } }; Ext.defer = Ext.Function.alias(Ext.Function, 'defer'); Ext.pass = Ext.Function.alias(Ext.Function, 'pass'); Ext.bind = Ext.Function.alias(Ext.Function, 'bind');
1.alias(object, methodName):将object的mothodName方法赋予给指定对象。
2.bind(fn,scope,args,appendArgs):将fn函数以scope作为上下文以args作为参数进行调用。
在JavaScript中,函数和其他值一样,也是数据,因此,它们可以从函数返回,被赋予给对象属性,存储在数组中,等等。
考虑下面的例子,其中包含了一个函数,他返回一个嵌套的函数。每次调用这个函数,它都返回一个函数。返回的函数的JavaScript代码总是相同的,但是,它所创建的作用域略为不同,因为外围函数的参数值在每次调用中都不同(也就是说,外围函数的每次调用的作用域链上,有一个不同的调用对象)。如果把返回的函数存储在一个数组中,然后来调用其中的每一个,将会看到每次返回一个不同的值。既然每个函数包含同样的JavaScript代码,并且每段代码都是从相同的作用域调用的,那么,唯一可能导致不同返回值的因素就是函数定义所在的作用域。
function makefunc(x) { return function() {return x;} } var a = [makefunc(0), makefunc(1), makefunc(2)]; alert(a[0]()); alert(a[1]()); alert(a[2]());