Extjs系列之一 開篇+function擴展

開篇:

用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裏面的其他不錯的使用介紹。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章