{"action":"opened","issue":{"url":"https://api.github.com/repos/10110001/blog/issues/3","repository_url":"https://api.github.com/repos/10110001/blog","labels_url":"https://api.github.com/repos/10110001/blog/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/10110001/blog/issues/3/comments","events_url":"https://api.github.com/repos/10110001/blog/issues/3/events","html_url":"https://github.com/10110001/blog/issues/3","id":334361670,"node_id":"MDU6SXNzdWUzMzQzNjE2NzA=","number":3,"title":"初识 JavaScript 依赖注入","user":{"login":"10110001","id":14888368,"node_id":"MDQ6VXNlcjE0ODg4MzY4","avatar_url":"https://avatars1.githubusercontent.com/u/14888368?v=4","gravatar_id":"","url":"https://api.github.com/users/10110001","html_url":"https://github.com/10110001","followers_url":"https://api.github.com/users/10110001/followers","following_url":"https://api.github.com/users/10110001/following{/other_user}","gists_url":"https://api.github.com/users/10110001/gists{/gist_id}","starred_url":"https://api.github.com/users/10110001/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/10110001/subscriptions","organizations_url":"https://api.github.com/users/10110001/orgs","repos_url":"https://api.github.com/users/10110001/repos","events_url":"https://api.github.com/users/10110001/events{/privacy}","received_events_url":"https://api.github.com/users/10110001/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-06-21T06:56:10Z","updated_at":"2018-06-21T06:56:10Z","closed_at":null,"author_association":"OWNER","body":"**写在最前**\r\n\r\n**什么是依赖注入**\r\n可以抽象为下面这张简易示意图：\r\n![image](https://user-images.githubusercontent.com/14888368/41702279-1a9a08e0-7562-11e8-82b5-cdf627e40038.png)\r\n按照上面图的流程中我们可以知道我们需要实现这么几件事：\r\n\r\n提供一个服务容器\r\n为目标函数注册需要的依赖\r\n获取目标函数注册的依赖项\r\n通过依赖项来查询对应服务\r\n将获取的依赖项传入目标函数\r\n\r\n**提供一个服务容器**\r\n\r\n        //假装提供一些服务\r\n           var services = { \r\n                 A: () => {console.log(1)}, \r\n                 B: () => {console.log(2)},\r\n                 C: () => {console.log(3)}\r\n              } \r\n\r\n**为目标函数注册需要的依赖**\r\n\r\n       // 目标函数 \r\n        function Service(A, B) { \r\n             A()\r\n             B()\r\n          } \r\n\r\n**获取目标函数注册的依赖项**\r\n\r\n        // 获取func的参数列表(依赖列表) \r\n           getFuncParams = function (func) { \r\n           var matches = func.toString().match(/^function\\s*[^\\(]*\\(\\s*([^\\)]*)\\)/m); \r\n           if (matches && matches.length > 1) \r\n               return matches[1].replace(/\\s+/, '').split(','); \r\n            return []; \r\n          }\r\n    \r\n实现原理为将传入的目标函数进行正则匹配，匹配出形参。这其中的关键点在于这段正则表达式：\r\n\r\n     /^function\\s*[^\\(]*\\(\\s*([^\\)]*)\\)/m\r\n\r\n其中  \\(\\s*([^\\)]*\r\n通过括号来提取匹配到function后面参数括号的内部内容，也就是可以得到参数字符串。这里面是运用了括号的提取数据的规则来获取的信息，规则如下：\r\n\r\n     var regex = /(\\d{4})-(\\d{2})-(\\d{2})/;\r\n     var string = \"2017-06-12\";\r\n       console.log( string.match(regex) ); \r\n      // => [\"2017-06-12\", \"2017\", \"06\", \"12\", index: 0, input: \"2017-06-12\"]\r\n\r\n结果数组中第一个元素为匹配结果，之后为括号内的数据，由此我们便可知道，这段正则通过括号的使用，获取到了整个形参作为一个字符串，之后再通过split进行拆分就得到了我们想要的结果。\r\n\r\n**通过依赖项来查询对应服务**\r\n\r\n     //简易实现\r\n     setFuncParams = function (params) { \r\n        for (var i in params) { \r\n        params[i] = services[params[i]]; \r\n      } \r\n        return params; \r\n      }; //依次对应服务中的项进行查找返回结果。\r\n\r\n**将获取的依赖项传入目标函数**\r\n\r\n     // 注射器 \r\n      function Injector(func, scope) { \r\n           return () => {\r\n           func.apply(scope || {}, setFuncParams(getFuncParams(func)));\r\n          } \r\n       } \r\n     // 实例化Service并调用方法 \r\n        var service = Injector(Service); \r\n        service();//1 2\r\n\r\n\r\n"}}
{"actor":{"display_login":"10110001"}}