zoukankan      html  css  js  c++  java
  • JavaScript中实现DI的原理(二)

    JavaScript中实现DI的原理

    在JavaScript中实现DI,看起来难,实际上原理很简单,它的核心技术是Function对象的toString()。我们都知道,对一个函数对象执行toString(),它的返回值是函数的源码,知道了这一点,接下来就简单的:我获取了函数源码,然后我对函数的声明进行解析,伪码如下:

    var giveMe = function(config) {
    };
    
    var registry = {};
    var inject = function(func, thisForFunc) {
        // 获取源码
        var source = func.toString();
        // 用正则表达式解析源码
        var matcher = source.match(/..表达式有些复杂,省略../);
        // 解析结果是各个参数的名称
        var objectIds = ....
        // 查阅出相应的对象,放到数组中准备作为参数传过去
        var objects = [];
        for (var i = 0; i < objectIds.length; ++i)
            objects.push(registry[objectIds[i]]);
        // 调用这个函数,并且把参数传过去
        func.apply(thisForFunc || func, objects)
    };
    
    inject(giveMe)

    当然,一个实际的DI系统需要考虑的问题比这要多很多,但是这段代码用来表现原理应该足够了。

    接下来我们再来看Angular中的DI实现:

    在Angular中,所有主要编程元素都需要通过某种方式注册进去,比如myModule.service('serviceName', function().... 这实际上就是把后面这个函数加入到一个容器中,要注意的是:angular全面实现了延迟初始化,也就是说,当这个对象没有被别人需要的时候,它是不会被创建的,这样对于提高性能有一定的帮助,特别是加快了启动速度。

    这里一个有趣的问题是:Angular的容器是什么。Angular不存在真正的全局对象,所以你可以放心的在同一个页面中放多个app,而不用担心他们互相干扰,但是容器又需要一个众所周知的地方来存放这些“名字和对象”的注册表(Registry),在Angular中,这个注册表就叫做module,所以,现在你应该知道为什么module的地位很重要了吧?不过一个app中可以存在很多不同名字的module,它们之间存在某些依赖关系,而这体现在module的声明语法中:angular.module('someModule', ['dep1', 'dep2]),这样划分module有利于程序的文件组织。

    根据DI的原理,一个自然的推论就是:被注入的对象通常都是单例,因为创建了一个,就可以始终使用它了,不需要多次创建。因此,如果你需要在angular中跨controller共享数据或者通讯,那么你可以创建一个service/value/constant等,然后把它们分别注入到两个controller中,而这两个controller将自然而然的共享同一个对象。

  • 相关阅读:
    第03组 团队git现场编程实战
    第二次结对编程作业
    团队项目-选题报告
    第一次结对编程作业
    第一次编程作业
    软件工程第一次作业
    第09组 团队Git现场编程实战
    第二次结对编程作业
    团队项目-需求分析报告
    团队项目-选题报告
  • 原文地址:https://www.cnblogs.com/aliwa/p/8492587.html
Copyright © 2011-2022 走看看