首頁 > web前端 > js教程 > 主體

JS反射與依賴注入使用案例分析

php中世界最好的语言
發布: 2018-05-31 14:37:52
原創
1547 人瀏覽過

這次帶給大家JS反射與依賴注入使用案例分析,JS反射與依賴注入使用的注意事項有哪些,下面就是實戰案例,一起來看一下。

對於javascript中的反射的理解,一直都是認為,利用數組對回調函數進行保存,之後在適當的時刻利用call或apply 方法,對回呼進行呼叫即可,一般如下操作:

首先定義兩個方法:

var service = function() {
  return { name: 'Service' };
}
var router = function() {
  return { name: 'Router' };
}
登入後複製

我們有另一個函數需要用到這兩個模組。

var doSomething = function(other) {
  var s = service();
  var r = router();
};
登入後複製

當然,我們希望能夠使用依賴注入的方式去做,把該控制權交給計算機去做,而不是人為的去調用如下:

var doSomething = injector.resolve('router,,service', function(a, b, c) {
  expect(a().name).to.be('Router');
  expect(b).to.be('Other');
  expect(c().name).to.be('Service');
});
doSomething("Other");
登入後複製

那麼我們可以造出一個反射方法如下:

var injector ={
    dependencies: {},
    register: function(key, value) {
      this.dependencies[key] = value;
    },
    resolve:function(deps, func, scope) {
      var args = [];
      for(var i=0; i<deps.length, d=deps[i]; i++) {
        if(this.dependencies[d]) {
          args.push(this.dependencies[d]);
        } else {
          throw new Error('Can\'t resolve ' + d);
        }
      }
      return function() {
        func.apply(scope || {}, args.concat(Array.prototype.slice.call(arguments, 0)));
      }
    }
};
登入後複製

如上程式碼,dependencies 用來保存回呼函數集合,resolve用來呼叫。

這也算是比較成熟ok的想法。

但是依舊問題存在幾點問題:

1 resolve 在進行呼叫時,deps參數列表順序必須保持一致。

2 這一點有點牽強,但也算。在呼叫時,需要再一次的輸入形參,而不能直接呼叫。

那麼為了解決以上問題,給出以下解決方案:

var injector ={
    dependencies: {},
    register: function(key, value) {
      this.dependencies[key] = value;
    },
    resolve: function() {
      var func, deps, scope, args = [], self = this;
      if(typeof arguments[0] === 'string') {
        func = arguments[1];
        deps = arguments[0].replace(/ /g, '').split(',');
        scope = arguments[2] || {};
      } else {
        func = arguments[0];
        deps = func.toString().match(/^function\s*[^]*\(\s*([^]*\(\s*([^]*)\)/m)[1].replace(/ /g, '').split(',');
        scope = arguments[1] || {};
      }
      return function() {
        var a = Array.prototype.slice.call(arguments, 0);
        for(var i=0; i<deps.length; i++) {
          var d = deps[i];
          args.push(self.dependencies[d] && d != '' ? self.dependencies[d] : a.shift());
        }
        func.apply(scope || {}, args);
      }
    }
};
登入後複製

利用正規對程式碼進行解析,解析出function 列表參數,再進行一一自動匹配傳值,那麼即可解決,順序必須一直問題,當然這也是當然最熱mvvm框架AngularJs採取的方式。

呼叫方式可以如下:

injector.resolve(['service,,router', function(service, router) {
}]);
登入後複製

你可能注意到在第一個參數後面有兩個逗號-注意

這不是筆誤。空值實際上代表“Other”參數(佔位符)。這顯示了我們是如何控制參數順序的。

最後還有一種方式,直接注入scope ,也就是直接注入作用域,那麼作用域被注入,也就不存在上述的傳參順序問題

因為不在需要傳遞參數,直接可以從作用域存取。

var injector = {
  dependencies: {},
  register: function(key, value) {
    this.dependencies[key] = value;
  },
  resolve: function(deps, func, scope) {
    var args = [];
    scope = scope || {};
    for(var i=0; i<deps.length, d=deps[i]; i++) {
      if(this.dependencies[d]) {
        scope[d] = this.dependencies[d];
      } else {
        throw new Error('Can\'t resolve ' + d);
      }
    }
    return function() {
      func.apply(scope || {}, Array.prototype.slice.call(arguments, 0));
    }
  }
}
var doSomething = injector.resolve(['service', 'router'], function(other) {
  expect(this.service().name).to.be('Service');
  expect(this.router().name).to.be('Router');
  expect(other).to.be('Other');
});
doSomething("Other");
登入後複製

我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

如何在微信小程式內開發驗證碼密碼輸入框功能

如何使用js統計頁面標籤數量

以上是JS反射與依賴注入使用案例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!