国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

AngularJS之依賴注入模擬實(shí)現(xiàn)

2019-11-20 09:12:37
字體:
供稿:網(wǎng)友

一、概述 

AngularJS有一經(jīng)典之處就是依賴注入,對(duì)于什么是依賴注入,熟悉spring的同學(xué)應(yīng)該都非常了解了,但,對(duì)于前端而言,還是比較新穎的。 

依賴注入,簡(jiǎn)而言之,就是解除硬編碼,達(dá)到解偶的目的。 

下面,我們看看AngularJS中常用的實(shí)現(xiàn)方式。 

方法一:推斷式注入聲明,假定參數(shù)名稱就是依賴的名稱。因此,它會(huì)在內(nèi)部調(diào)用函數(shù)對(duì)象的toString()方法,分析并提取出函數(shù)參數(shù)列表,然后通過$injector將這些參數(shù)注入進(jìn)對(duì)象實(shí)例。 

如下: 

//方法一:推斷式注入聲明,假定參數(shù)名稱就是依賴的名稱。//因此,它會(huì)在內(nèi)部調(diào)用函數(shù)對(duì)象的toString()方法,分析并提取出函數(shù)參數(shù)列表,//然后通過$injector將這些參數(shù)注入進(jìn)對(duì)象實(shí)例injector.invoke(function($http, $timeout){ //TODO});

方法二:行內(nèi)注入聲明,允許我們?cè)诤瘮?shù)定義時(shí),直接傳入一個(gè)參數(shù)數(shù)組,數(shù)組包含了字符串和函數(shù),其中,字符串代表依賴名,函數(shù)代表目標(biāo)函數(shù)對(duì)象。
 如下:

//方法二:行內(nèi)注入聲明,允許我們?cè)诤瘮?shù)定義時(shí),直接傳入一個(gè)參數(shù)數(shù)組,//數(shù)組包含了字符串和函數(shù),其中,字符串代表依賴名,函數(shù)代表目標(biāo)函數(shù)對(duì)象。module.controller('name', ['$http', '$timeout', function($http, $timeout){ //TODO}]); 

看了上述代碼,心中有一疑問,這些是怎么實(shí)現(xiàn)的呢? 

哈哈,下面,我們就來一起模擬一下這些依賴注入方式,從而了解它們。 

二、搭建基本骨架 

依賴注入的獲取過程就是,通過字段映射,從而獲取到相應(yīng)的方法。 

故而,要實(shí)現(xiàn)一個(gè)基本的依賴注入,我們需要一個(gè)存儲(chǔ)空間(dependencies),存儲(chǔ)所需鍵值(key/value);一個(gè)注冊(cè)方法(register),用于新增鍵值對(duì)到存儲(chǔ)空間中;還有一個(gè)就是核心實(shí)現(xiàn)方法(resolve),通過相關(guān)參數(shù),到存儲(chǔ)空間中獲得對(duì)應(yīng)的映射結(jié)果。 

So,基本骨架如下: 

var injector = { dependencies: {}, register: function(key, value){ this.dependencies[key] = value; return this; }, resolve: function(){     }};

三、完善核心方法resolve 

從我們搭建的基本骨架中,可以發(fā)現(xiàn),重點(diǎn)其實(shí)resolve方法,用于實(shí)現(xiàn)我們具體形式的依賴注入需求。 

首先,我們來實(shí)現(xiàn),如下形式的依賴注入:推斷式注入聲明。 

如下: 

injector.resolve(function(Monkey, Dorie){ Monkey(); Dorie();}); 

要實(shí)現(xiàn)上述效果,我們可以利用函數(shù)的toString()方法,我們可以將函數(shù)轉(zhuǎn)換成字符串,從而通過正則表達(dá)式獲得參數(shù)名,即key值。 然后通過key值,在存儲(chǔ)空間dependencies找value值,沒找到對(duì)應(yīng)值,則報(bào)錯(cuò)。 

實(shí)現(xiàn)如下: 

var injector = { dependencies: {}, register: function(key, value){ this.dependencies[key] = value; return this; }, resolve: function(){ var func, deps, args = [], scope = null; func = arguments[0]; //獲取函數(shù)的參數(shù)名 deps = func.toString().match(/^function/s*[^/(]*/(/s*([^/)]*)/)/m)[1].replace(/ /g, '').split(','); scope = arguments[1] || {}; for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){  if(this.dependencies[d]){  args.push(this.dependencies[d]);  }else{  throw new Error('Can/'t find ' + d);  } } func.apply(scope, args);    }};

測(cè)試代碼,如下: 

<!DOCTYPE html> <head> <meta charset="utf-8"/> </head> <body> <script>  var injector = {  dependencies: {},  register: function(key, value){   this.dependencies[key] = value;   return this;  },  resolve: function(){   var func, deps, args = [], scope = null;   func = arguments[0];   //獲取函數(shù)的參數(shù)名   deps = func.toString().match(/^function/s*[^/(]*/(/s*([^/)]*)/)/m)[1].replace(/ /g, '').split(',');   scope = arguments[1] || {};   for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){   if(this.dependencies[d]){    args.push(this.dependencies[d]);   }else{    throw new Error('Can/'t find ' + d);   }   }   func.apply(scope, args);     }  };  //測(cè)試代碼  injector.register('Monkey', function(){  console.log('Monkey');  }).register('Dorie', function(){  console.log('Dorie');  });  injector.resolve(function(Monkey, Dorie){  Monkey();  Dorie();  console.log('-.-');  });  </script> </body></html>

推斷式注入聲明,有個(gè)缺點(diǎn),就是不能利用壓縮工具壓縮,因?yàn)槲覀兪峭ㄟ^函數(shù)的參數(shù)作為依賴的,當(dāng)我們壓縮時(shí),會(huì)將參數(shù)名改掉,參數(shù)名都變了,那肯定撲街咯。 

那么下面,我們就看看行內(nèi)注入聲明,它可以彌補(bǔ)這缺點(diǎn)。 

實(shí)現(xiàn)行內(nèi)注入聲明,如下:

 injector.resolve(['Monkey', 'Dorie', function(M, D){ M(); D();}]); 

利用typeof判斷arguments[0]的類型可以辨別并獲得依賴參數(shù)和函數(shù)。 

實(shí)現(xiàn)如下: 

var injector = { dependencies: {}, register: function(key, value){ this.dependencies[key] = value; return this; }, resolve: function(){ var firstParams, func, deps = [], scope = null, args = []; firstParams = arguments[0]; scope = arguments[1] || {}; //獲得依賴參數(shù) for(var i = 0, len = firstParams.length; i < len; i++){  var val = firstParams[i],  type = typeof val;  if(type === 'string'){  deps.push(val);  }else if(type === 'function'){  func = val;  } } //通過依賴參數(shù),找到關(guān)聯(lián)值 for(i = 0, len = deps.length; i < len, d = deps[i]; i++){  if(this.dependencies[d]){  args.push(this.dependencies[d]);  }else{  throw new Error('Can/'t find ' + d);  } } func.apply(scope || {}, args);    }};

測(cè)試代碼,如下: 

<!DOCTYPE html> <head> <meta charset="utf-8"/> </head> <body> <script>  var injector = {  dependencies: {},  register: function(key, value){   this.dependencies[key] = value;   return this;  },  resolve: function(){   var firstParams, func, deps = [], scope = null, args = [];   firstParams = arguments[0];   scope = arguments[1] || {};   //獲得依賴參數(shù)   for(var i = 0, len = firstParams.length; i < len; i++){   var val = firstParams[i],    type = typeof val;   if(type === 'string'){    deps.push(val);   }else if(type === 'function'){    func = val;   }   }   //通過依賴參數(shù),找到關(guān)聯(lián)值   for(i = 0, len = deps.length; i < len, d = deps[i]; i++){   if(this.dependencies[d]){    args.push(this.dependencies[d]);   }else{    throw new Error('Can/'t find ' + d);   }   }   func.apply(scope || {}, args);     }  };  //測(cè)試代碼  injector.register('Monkey', function(){  console.log('Monkey');  }).register('Dorie', function(){  console.log('Dorie');  });  injector.resolve(['Monkey','Dorie',function(M, D){  M();  D();  console.log('-.-');  }]);  </script> </body></html>

因?yàn)樾袃?nèi)注入聲明,是通過字符串的形式作為依賴參數(shù),so,壓縮也不怕咯。
 最后,我們將上面實(shí)現(xiàn)的兩種方法,整合到一起,就可以為所欲為啦。
 那,就合并下吧,如下: 

var injector = { dependencies: {}, register: function(key, value){ this.dependencies[key] = value; return this; }, resolve: function(){ var firstParams, func, deps = [], scope = null, args = []; firstParams = arguments[0]; scope = arguments[1] || {}; //判斷哪種形式的注入 if(typeof firstParams === 'function'){  func = firstParams;  deps = func.toString().match(/^function/s*[^/(]*/(/s*([^/)]*)/)/m)[1].replace(/ /g, '').split(','); }else{  for(var i = 0, len = firstParams.length; i < len; i++){  var val = firstParams[i],   type = typeof val;  if(type === 'string'){   deps.push(val);  }else if(type === 'function'){   func = val;  }  }  } //通過依賴參數(shù),找到關(guān)聯(lián)值 for(i = 0, len = deps.length; i < len, d = deps[i]; i++){  if(this.dependencies[d]){  args.push(this.dependencies[d]);  }else{  throw new Error('Can/'t find ' + d);  } } func.apply(scope || {}, args);    }};

四、花絮―RequireJS之依賴注入 

依賴注入并非在AngularJS中有,倘若你使用過RequireJS,那么下面這種形式,不會(huì)陌生吧:

 require(['Monkey', 'Dorie'], function(M, D){ //TODO }); 

通過,上面我們一步步的模擬AngularJS依賴注入的實(shí)現(xiàn),想必,看到這,你自己也會(huì)豁然開朗,換湯不換藥嘛。 

模擬實(shí)現(xiàn)如下: 

var injector = { dependencies: {}, register: function(key, value){ this.dependencies[key] = value; return this; }, resolve: function(deps, func, scope){ var args = []; for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){  if(this.dependencies[d]){  args.push(this.dependencies[d]);  }else{  throw new Error('Can/'t resolve ' + d);  } } func.apply(scope || {}, args); }};

測(cè)試代碼如下: 

<!DOCTYPE html> <head> <meta charset="utf-8"/> </head> <body> <script>  var injector = {  dependencies: {},  register: function(key, value){   this.dependencies[key] = value;   return this;  },  resolve: function(deps, func, scope){   var args = [];   for(var i = 0, len = deps.length; i < len, d = deps[i]; i++){   if(this.dependencies[d]){    args.push(this.dependencies[d]);   }else{    throw new Error('Can/'t resolve ' + d);   }   }   func.apply(scope || {}, args);  }  };  //測(cè)試代碼    injector.register('Monkey', function(){  console.log('Monkey');  }).register('Dorie', function(){  console.log('Dorie');  });  injector.resolve(['Monkey', 'Dorie'], function(M, D){  M();  D();  console.log('-.-');  });  </script> </body></html>

五、參考 

1、AngularJS應(yīng)用開發(fā)思維之3:依賴注入 
2、Dependency injection in JavaScript

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 华亭县| 固安县| 孟州市| 曲水县| 平谷区| 大连市| 太康县| 西平县| 闵行区| 柯坪县| 定远县| 桑植县| 奈曼旗| 湘阴县| 囊谦县| 余江县| 四会市| 德钦县| 渭南市| 威远县| 正安县| 文山县| 马尔康县| 巩留县| 葵青区| 大悟县| 漳州市| 石门县| 临猗县| 镇雄县| 苏尼特左旗| 桂平市| 永胜县| 肥西县| 军事| 临夏县| 勐海县| 洛阳市| 林西县| 炉霍县| 通化市|