X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..HEAD:/docs/source/Function.html diff --git a/docs/source/Function.html b/docs/source/Function.html index 636d6ff4..f02f436c 100644 --- a/docs/source/Function.html +++ b/docs/source/Function.html @@ -3,8 +3,8 @@
/** - * @class Ext.Function +/** + * @class Function * - * A collection of useful static methods to deal with function callbacks - * @singleton + * Every function in JavaScript is actually a `Function` object. + * + * `Function` objects created with the `Function` constructor are parsed when the + * function is created. This is less efficient than declaring a function and + * calling it within your code, because functions declared with the function + * statement are parsed with the rest of the code. + * + * All arguments passed to the function are treated as the names of the + * identifiers of the parameters in the function to be created, in the order in + * which they are passed. + * + * Invoking the `Function` constructor as a function (without using the `new` + * operator) has the same effect as invoking it as a constructor. + * + * # Specifying arguments with the `Function` constructor + * + * The following code creates a `Function` object that takes two arguments. + * + * // Example can be run directly in your JavaScript console + * + * // Create a function that takes two arguments and returns the sum of those + * arguments + * var adder = new Function("a", "b", "return a + b"); + * + * // Call the function + * adder(2, 6); + * // > 8 + * + * The arguments "a" and "b" are formal argument names that are used in the + * function body, "return a + b". + * + * <div class="notice"> + * Documentation for this class comes from <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function">MDN</a> + * and is available under <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons: Attribution-Sharealike license</a>. + * </div> */ -Ext.Function = { - - /** - * A very commonly used method throughout the framework. It acts as a wrapper around another method - * which originally accepts 2 arguments for `name` and `value`. - * The wrapped function then allows "flexible" value setting of either: - * - * - `name` and `value` as 2 arguments - * - one single object argument with multiple key - value pairs - * - * For example: - * - * var setValue = Ext.Function.flexSetter(function(name, value) { - * this[name] = value; - * }); - * - * // Afterwards - * // Setting a single name - value - * setValue('name1', 'value1'); - * - * // Settings multiple name - value pairs - * setValue({ - * name1: 'value1', - * name2: 'value2', - * name3: 'value3' - * }); - * - * @param {Function} setter - * @returns {Function} flexSetter - */ - 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; - }; - }, - - /** - * Create a new function from the provided `fn`, change `this` to the provided scope, optionally - * overrides arguments for the call. (Defaults to the arguments passed by the caller) - * - * {@link Ext#bind Ext.bind} is alias for {@link Ext.Function#bind Ext.Function.bind} - * - * @param {Function} fn The function to delegate. - * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed. - * **If omitted, defaults to the browser window.** - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Function} The new function - */ - bind: function(fn, scope, args, appendArgs) { - var method = fn, - slice = Array.prototype.slice; - - return function() { - var callArgs = args || arguments; - if (appendArgs === true) { - callArgs = slice.call(arguments, 0); - callArgs = callArgs.concat(args); - } - else if (Ext.isNumber(appendArgs)) { - callArgs = slice.call(arguments, 0); // copy arguments first - Ext.Array.insert(callArgs, appendArgs, args); - } - - return method.apply(scope || window, callArgs); - }; - }, - - /** - * Create a new function from the provided `fn`, the arguments of which are pre-set to `args`. - * New arguments passed to the newly created callback when it's invoked are appended after the pre-set ones. - * This is especially useful when creating callbacks. - * - * For example: - * - * var originalFunction = function(){ - * alert(Ext.Array.from(arguments).join(' ')); - * }; - * - * var callback = Ext.Function.pass(originalFunction, ['Hello', 'World']); - * - * callback(); // alerts 'Hello World' - * callback('by Me'); // alerts 'Hello World by Me' - * - * {@link Ext#pass Ext.pass} is alias for {@link Ext.Function#pass Ext.Function.pass} - * - * @param {Function} fn The original function - * @param {Array} args The arguments to pass to new callback - * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed. - * @return {Function} The new callback function - */ - pass: function(fn, args, scope) { - if (args) { - args = Ext.Array.from(args); - } - - return function() { - return fn.apply(scope, args.concat(Ext.Array.toArray(arguments))); - }; - }, - - /** - * Create an alias to the provided method property with name `methodName` of `object`. - * Note that the execution scope will still be bound to the provided `object` itself. - * - * @param {Object/Function} object - * @param {String} methodName - * @return {Function} aliasFn - */ - alias: function(object, methodName) { - return function() { - return object[methodName].apply(object, arguments); - }; - }, - - /** - * 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. Example usage: - * - * 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 = Ext.Function.createInterceptor(sayHi, function(name){ - * return name == 'Brian'; - * }); - * - * sayHiToFriend('Fred'); // no alert - * sayHiToFriend('Brian'); // alerts "Hi, Brian" - * - * @param {Function} origFn The original function. - * @param {Function} newFn The function to call before the original - * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed. - * **If omitted, defaults to the scope in which the original function is called or the browser window.** - * @param {Mixed} returnValue (optional) The value to return if the passed function return false (defaults to null). - * @return {Function} The new function - */ - 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; - }; - } - }, - - /** - * Creates a delegate (callback) which, when called, executes after a specific delay. - * - * @param {Function} fn The function which will be called on a delay when the returned function is called. - * Optionally, a replacement (or additional) argument list may be specified. - * @param {Number} delay The number of milliseconds to defer execution by whenever called. - * @param {Object} scope (optional) The scope (`this` reference) used by the function at execution time. - * @param {Array} args (optional) Override arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position. - * @return {Function} A function which, when called, executes the original function after the specified delay. - */ - 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); - }; - }, - - /** - * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: - * - * var sayHi = function(name){ - * alert('Hi, ' + name); - * } - * - * // executes immediately: - * sayHi('Fred'); - * - * // executes after 2 seconds: - * Ext.Function.defer(sayHi, 2000, this, ['Fred']); - * - * // this syntax is sometimes useful for deferring - * // execution of an anonymous function: - * Ext.Function.defer(function(){ - * alert('Anonymous'); - * }, 100); - * - * {@link Ext#defer Ext.defer} is alias for {@link Ext.Function#defer Ext.Function.defer} - * - * @param {Function} fn The function to defer. - * @param {Number} millis The number of milliseconds for the setTimeout call - * (if less than or equal to 0 the function is executed immediately) - * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed. - * **If omitted, defaults to the browser window.** - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Number} The timeout id that can be used with clearTimeout - */ - 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; - }, - - /** - * 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 function is called with the parameters of the original function. Example usage: - * - * var sayHi = function(name){ - * alert('Hi, ' + name); - * } - * - * sayHi('Fred'); // alerts "Hi, Fred" - * - * var sayGoodbye = Ext.Function.createSequence(sayHi, function(name){ - * alert('Bye, ' + name); - * }); - * - * sayGoodbye('Fred'); // both alerts show - * - * @param {Function} origFn The original function. - * @param {Function} newFn The function to sequence - * @param {Object} scope (optional) The scope (`this` reference) in which the passed function is executed. - * If omitted, defaults to the scope in which the original function is called or the browser window. - * @return {Function} The new function - */ - 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; - }; - } - }, - - /** - * Creates a delegate function, optionally with a bound scope which, when called, buffers - * the execution of the passed function for the configured number of milliseconds. - * If called again within that period, the impending invocation will be canceled, and the - * timeout period will begin again. - * - * @param {Function} fn The function to invoke on a buffered timer. - * @param {Number} buffer The number of milliseconds by which to buffer the invocation of the - * function. - * @param {Object} scope (optional) The scope (`this` reference) in which - * the passed function is executed. If omitted, defaults to the scope specified by the caller. - * @param {Array} args (optional) Override arguments for the call. Defaults to the arguments - * passed by the caller. - * @return {Function} A function which invokes the passed function after buffering for the specified time. - */ - 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); - }; - }(); - }, +/** + * @method constructor + * Creates new Function object. + * + * @param {String...} args + * Names to be used by the function as formal argument names. Each must be a + * string that corresponds to a valid JavaScript identifier or a list of such + * strings separated with a comma; for example "`x`", "`theValue`", or "`a,b`". + * @param {String} functionBody + * A string containing the JavaScript statements comprising the function + * definition. + */ - /** - * Creates a throttled version of the passed function which, when called repeatedly and - * rapidly, invokes the passed function only after a certain interval has elapsed since the - * previous invocation. - * - * This is useful for wrapping functions which may be called repeatedly, such as - * a handler of a mouse move event when the processing is expensive. - * - * @param {Function} fn The function to execute at a regular time interval. - * @param {Number} interval The interval **in milliseconds** on which the passed function is executed. - * @param {Object} scope (optional) The scope (`this` reference) in which - * the passed function is executed. If omitted, defaults to the scope specified by the caller. - * @returns {Function} A function which invokes the passed function at the specified interval. - */ - createThrottled: function(fn, interval, scope) { - var lastCallTime, elapsed, lastArgs, timer, execute = function() { - fn.apply(scope || this, lastArgs); - lastCallTime = new Date().getTime(); - }; +// Properties - return function() { - elapsed = new Date().getTime() - lastCallTime; - lastArgs = arguments; +/** + * @property {Number} length + * Specifies the number of arguments expected by the function. + */ - clearTimeout(timer); - if (!lastCallTime || (elapsed >= interval)) { - execute(); - } else { - timer = setTimeout(execute, interval - elapsed); - } - }; - } -}; +//Methods -/** - * @method - * @member Ext - * @alias Ext.Function#defer +/** + * @method apply + * Applies the method of another object in the context of a different object (the + * calling object); arguments can be passed as an Array object. + * + * You can assign a different this object when calling an existing function. `this` refers to the + * current object, the calling object. With `apply`, you can write a method once and then inherit it + * in another object, without having to rewrite the method for the new object. + * + * `apply` is very similar to call, except for the type of arguments it supports. You can use an + * arguments array instead of a named set of parameters. With apply, you can use an array literal, for + * example, `fun.apply(this, ['eat', 'bananas'])`, or an Array object, for example, `fun.apply(this, + * new Array('eat', 'bananas'))`. + * + * You can also use arguments for the `argsArray` parameter. `arguments` is a local variable of a + * function. It can be used for all unspecified arguments of the called object. Thus, you do not have + * to know the arguments of the called object when you use the `apply` method. You can use arguments + * to pass all the arguments to the called object. The called object is then responsible for handling + * the arguments. + * + * Since ECMAScript 5th Edition you can also use any kind of object which is array like, so in + * practice this means it's going to have a property length and integer properties in the range + * `[0...length)`. As an example you can now use a NodeList or a own custom object like `{'length': 2, + * '0': 'eat', '1': 'bananas'}`. + * + * You can use `apply` to chain constructors for an object, similar to Java. In the following example, + * the constructor for the `Product` object is defined with two parameters, `name` and `value`. Two + * other functions `Food` and `Toy` invoke `Product` passing `this` and `arguments`. `Product` + * initializes the properties `name` and `price`, both specialized functions define the category. In + * this example, the `arguments` object is fully passed to the product constructor and corresponds to + * the two defined parameters. + * + * function Product(name, price) { + * this.name = name; + * this.price = price; + * + * if (price < 0) + * throw RangeError('Cannot create product "' + name + '" with a negative price'); + * return this; + * } + * + * function Food(name, price) { + * Product.apply(this, arguments); + * this.category = 'food'; + * } + * Food.prototype = new Product(); + * + * function Toy(name, price) { + * Product.apply(this, arguments); + * this.category = 'toy'; + * } + * Toy.prototype = new Product(); + * + * var cheese = new Food('feta', 5); + * var fun = new Toy('robot', 40); + * + * Clever usage of `apply` allows you to use built-ins functions for some tasks that otherwise + * probably would have been written by looping over the array values. As an example here we are going + * to use Math.max/Math.min to find out the maximum/minimum value in an array. + * + * //min/max number in an array + * var numbers = [5, 6, 2, 3, 7]; + * + * //using Math.min/Math.max apply + * var max = Math.max.apply(null, numbers); // This about equal to Math.max(numbers[0], ...) or + * // Math.max(5, 6, ..) + * var min = Math.min.apply(null, numbers); + * + * //vs. simple loop based algorithm + * max = -Infinity, min = +Infinity; + * + * for (var i = 0; i < numbers.length; i++) { + * if (numbers[i] > max) + * max = numbers[i]; + * if (numbers[i] < min) + * min = numbers[i]; + * } + * + * But beware: in using `apply` this way, you run the risk of exceeding the JavaScript engine's + * argument length limit. The consequences of applying a function with too many arguments (think more + * than tens of thousands of arguments) vary across engines, because the limit (indeed even the nature + * of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception. More + * perniciously, others will arbitrarily limit the number of arguments actually passed to the applied + * function. (To illustrate this latter case: if such an engine had a limit of four arguments [actual + * limits are of course significantly higher], it would be as if the arguments 5, 6, 2, 3 had been + * passed to apply in the examples above, rather than the full array.) If your value array might grow + * into the tens of thousands, use a hybrid strategy: apply your function to chunks of the array at a + * time: + * + * function minOfArray(arr) + * { + * var min = Infinity; + * var QUANTUM = 32768; + * for (var i = 0, len = arr.length; i < len; i += QUANTUM) + * { + * var submin = Math.min.apply(null, numbers.slice(i, Math.min(i + QUANTUM, len))); + * min = Math.min(submin, min); + * } + * return min; + * } + * + * var min = minOfArray([5, 6, 2, 3, 7]); + * + * @param {Object} thisArg The value of this provided for the call to fun. Note that this may not be + * the actual value seen by the method: if the method is a function in non-strict mode code, null and + * undefined will be replaced with the global object, and primitive values will be boxed. + * @param {Array} argsArray An array like object, specifying the arguments with which fun should be + * called, or null or undefined if no arguments should be provided to the function. + * @return {Object} Returns what the function returns. */ -Ext.defer = Ext.Function.alias(Ext.Function, 'defer'); -/** - * @method - * @member Ext - * @alias Ext.Function#pass +/** + * @method call + * Calls (executes) a method of another object in the context of a different + * object (the calling object); arguments can be passed as they are. + * + * You can assign a different this object when calling an existing function. `this` refers to the + * current object, the calling object. + * + * With `call`, you can write a method once and then inherit it in another object, without having to + * rewrite the method for the new object. + * + * You can use call to chain constructors for an object, similar to Java. In the following example, + * the constructor for the product object is defined with two parameters, name and value. Another + * object, `prod_dept`, initializes its unique variable (`dept`) and calls the constructor for + * `product` in its constructor to initialize the other variables. + * + * function Product(name, price) { + * this.name = name; + * this.price = price; + * + * if (price < 0) + * throw RangeError('Cannot create product "' + name + '" with a negative price'); + * return this; + * } + * + * function Food(name, price) { + * Product.call(this, name, price); + * this.category = 'food'; + * } + * Food.prototype = new Product(); + * + * function Toy(name, price) { + * Product.call(this, name, price); + * this.category = 'toy'; + * } + * Toy.prototype = new Product(); + * + * var cheese = new Food('feta', 5); + * var fun = new Toy('robot', 40); + * + * In this purely constructed example, we create anonymous function and use `call` to invoke it on + * every object in an array. The main purpose of the anonymous function here is to add a print + * function to every object, which is able to print the right index of the object in the array. + * Passing the object as `this` value was not strictly necessary, but is done for explanatory purpose. + * + * var animals = [ + * {species: 'Lion', name: 'King'}, + * {species: 'Whale', name: 'Fail'} + * ]; + * + * for (var i = 0; i < animals.length; i++) { + * (function (i) { + * this.print = function () { + * console.log('#' + i + ' ' + this.species + ': ' + this.name); + * } + * }).call(animals[i], i); + * } + * + * @param {Object} thisArg The value of this provided for the call to `fun`.Note that this may not be + * the actual value seen by the method: if the method is a function in non-strict mode code, `null` + * and `undefined` will be replaced with the global object, and primitive values will be boxed. + * @param {Object...} args Arguments for the object. + * @return {Object} Returns what the function returns. */ -Ext.pass = Ext.Function.alias(Ext.Function, 'pass'); -/** - * @method - * @member Ext - * @alias Ext.Function#bind - */ -Ext.bind = Ext.Function.alias(Ext.Function, 'bind'); -+/** + * @method toString + * Returns a string representing the source code of the function. Overrides the + * `Object.toString` method. + * + * The {@link Function} object overrides the `toString` method of the Object object; it does + * not inherit Object.toString. For `Function` objects, the `toString` method returns a string + * representation of the object. + * + * JavaScript calls the `toString` method automatically when a `Function` is to be represented as a + * text value or when a Function is referred to in a string concatenation. + * + * For `Function` objects, the built-in `toString` method decompiles the function back into the + * JavaScript source that defines the function. This string includes the `function` keyword, the + * argument list, curly braces, and function body. + * + * @return {String} The function as a string. + */