JS方法代理,js代理

來源:互聯網
上載者:User

JS方法代理,js代理

作者:Jiang, Jilin

JS作為一門指令碼語言,十分容易上手。外加其靈活性,可以輕而易舉地擴充功能。今天,我們就聊聊JS的方法代理。方法代理是指令碼語言中常見的方法擴充形式。這種靈活的形式優點在於遇到複雜的JS代碼需要擴充時,可以相對簡單的抽取並修改。但是,其缺點也十分明顯,會造成代碼的片段化,因而是一把雙刃劍。

基本形式

var _func = obj.func;

obj.func = function() {

         return _func();

};

 

此處,obj的func方法是原始方法。我們使用一個_func變數儲存該方法,之後重寫func方法,返回調用原始的方法。相當的好理解。

不定長參數

有時候,我們會遇到不定長參數的形式。那麼我們可以做以下更改:

var _func = obj.func;

obj.func = function() {

         return _func.apply(this, arguments);

};

 

寫到這裡,JS方法代理的兩種形式已經寫完了。這時,你可能會疑惑這種方法代理有什麼用?那麼,就跟隨我看看幾個例子吧:

 

重寫靜態方法

出於某些原因,我們需要在console列印的同時,將列印資料轉送到指定伺服器上使用者協助統計資料。而在開發過程中,直接使用了原生態的console.log方法輸出。那麼,我們就可做如下修改。

         首先,構建代理方法:

var _log = console.log;

console.log = function() {

         return _log.apply(this, arguments);

};

 

接著,插入ajax調用邏輯:

console.log = function() {

         var _args = Array.prototype.slice.call(arguments);

         $.post("srvAddr", {userID: userID, args: _args});

         return _log.apply(this, arguments);

};

 

 

可以很容易預見效果:



原型代理

有時候,我們需要直接接管一個類的方法。那麼相應的,我們就要將其prototype中的方法做代理。現在我們假設要使得Array預設支援數字排序:

var _sort = Array.prototype.sort;

Array.prototype.sort = function() {

         _sort.apply(this, arguments);

};

我們首先檢測數組中的元素是否是數字,如果是則按照數字排序,否則就按照預設排序:

var _sort = Array.prototype.sort;

Array.prototype.sort = function() {

         var _isNum = true;

         for(var i = 0 ; i < this.length ; i += 1) {

                   if(typeof this[i] !== "number") {

                            _isNum = false;

                            break;

                   }

         }

 

         if(_isNum) {

                   return _sort.call(this, function(a, b) {

                            return a - b;

                   });

         } else {

                   return _sort.apply(this, arguments);

         }

};

原始排序方式(將數字轉換成字元排序)

代理後排序方式

 

注意:此處僅作為原型方法代理的例子。在實際開發中,應該盡量避免對原生對象原型方法做代理。

 

重載

在jQuery中,toggle方法擁有多種重載,其中一個為toggle(display),通過接受boolean參數來決定元素顯示還是隱藏。而fadeToggle方法則不接受該參數。讓我們進行簡單的代理,使其支援boolean參數:

var _fadeToggle = $.fn.fadeToggle;

 

$.fn.fadeToggle = function(display) {

         if(arguments.length === 1 && typeof display === "boolean") {

                   if(display) {

                            return this.fadeIn();

                   } else {

                            return this.fadeOut();

                   }

         }

         return _fadeToggle.apply(this, arguments);

};

通過參數長度和接收參數類型類型判斷是否調用fadeIn或fadeOut方法。如果不匹配則調用原來的fadeToggle方法。以此類推,slideToggle也可以同樣適用。

 

*繼承

繼承中,我們有時候會需要調用父類方法來實現。這和java中的super有些類似。一個簡單的例子。我們定義了一個Person,可以laugh。同時定義一個Robot繼承,是其沿用Person的laugh但是稍作修改:

var Person = function() {

         this.name = "";

         this.laugh = function() {

                   return "Ha ha!";

         };

         return this;

};

 

var Robot = function() {

         Person.apply(this);

         var _laugh = this.laugh;

         this.laugh = function() {

                   return encodeURIComponent(_laugh());

         };

         return this;

};

 

劫持

說到劫持,則和安全性開始掛鈎了。如今大多數網站都習慣於使用開源的js庫來開發,但是如果碰巧被插入了惡意代碼,那麼安全也就變得不安全了(例如chrome中大量未經驗證的遊覽器外掛程式)。以下,我們將舉幾個劫持的例子。

 

Ajax劫持

不少人以為,通過閉包的方式將重要使用者參數儲存在範圍內(例如動態產生的secureID),那麼即便是被插入了惡意代碼也無法擷取到,從而無法偽造ajax請求來擷取重要訊息似乎就足夠了。但是如果整個ajax請求被攔截了呢?

var _ajax = $.ajax;

 

$.ajax = function() {

         var $p = _ajax.apply($, arguments);

         $p.done(function(data) {

                   // Do something...

         });

         return $p;

};

jQuery中所有ajax請求(get,post,getJSON)最終都會調用$.ajax來實現。而通過方法代理直接劫持$.ajax方法並返回一個正常promise對象,會使得頁面指令碼運行毫無影響。但是實際上資料已經被劫持走了。

 

Array劫持

         Array擁有不少原型方法,例如push,pop,shift,unshift等等。我們只需要簡單的代理數組操作方法,便可以截獲資料。

var _push = Array.prototype.push;

Array.prototype.push = function() {

         // Do something...

         return _push.apply(this, arguments);

};

 

好了,以上就是這次的方法代理介紹。由於方法代理會混亂代碼邏輯使得代碼結構變得不易理解。在日常開發過程中,我們應該盡量避免使用它。只有在代理重載,或者更改難以理解的遺留代碼的部分邏輯時使用它。從而避免將雙刃劍誤傷了自己。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.