简体   繁体   English

如何将同一个闭包下的对象分隔到不同的文件中

[英]How can I seperate objects that is under same closure into different files

I have following structure for my client; 我的客户有以下结构;

var myObject = (function(){
    var mainObjectList = [];
    var globalObject = {
            init:function(mainObjectId){
                var logger = {};
                var utilityObject1 = {};
                var utilityObject2 = {};
                var mainObject = {};
                mainObjectList.push(mainObject);
            },//init
            someOtherMethods:function(){}
        };//globalObject
    return globalObject;
})();

with my client I can say myObject.init(5); 和我的客户我可以说myObject.init(5); and create a new structure. 并创建一个新的结构。 My problem is I have a lot of utility objects inside init function closure (logger, utilityObject1, utilityObject2..). 我的问题是我在init函数闭包中有很多实用程序对象(logger,utilityObject1,utilityObject2 ..)。 My total file exceeded 1000 lines so I want to separate all utility objects into different files to have a better project. 我的总文件超过了1000行,所以我想将所有实用程序对象分成不同的文件以获得更好的项目。 for example I could separate logger, utilityObject1 , utilityObject2 to their own files. 例如,我可以将logger,utilityObject1,utilityObject2分离到自己的文件中。 the problem is since objects are in closure I cannot just add them to main object in separate files. 问题是因为对象处于闭包状态,我不能只将它们添加到单独文件中的主对象中。 so I thought of following injection method. 所以我想到了以下注射方法。

//start of file1
var myObject = (function(){
    var mainObjectList = [];
    var globalObject = {
            init:function(mainObjectId){
                var logger;
                var utilityObject1 = {};
                var utilityObject2 = {};
                var mainObject = {};
                mainObjectList.push(mainObject);
            },//init
            someOtherMethods:function(){},
            injectLogger:function(creator){
                this.logger = creator();
            }
        };//globalObject
    return globalObject;
})();
//start of file2
myObject.injectLogger(function(){return {};});

That way I can separate my files for development. 这样我就可以分开我的文件进行开发了。 but in production I can concatenate files to have one file. 但在生产中我可以连接文件以拥有一个文件。 But I have some problems with this design. 但是这个设计有些问题。 I just added an accessible injectLogger function into myObject. 我刚刚在myObject中添加了一个可访问的injectLogger函数。 and my logger cannot use other local variables in closure now(I have to pass them to creator object now). 并且我的记录器现在不能在闭包中使用其他局部变量(我现在必须将它们传递给creator对象)。 My question is is there any other way to separate that kind of code into files. 我的问题是有没有其他方法将这种代码分成文件。 (maybe an external utility.) (也许是一个外部工具。)

I like to use google's closure compiler http://code.google.com/closure/compiler/ 我喜欢使用谷歌的闭包编译器http://code.google.com/closure/compiler/

If you don't want to use something like that, you might try this sort of thing: (Make sure you load globalObject.js first to define the variable). 如果您不想使用类似的东西,您可以尝试这样的事情:(确保首先加载globalObject.js以定义变量)。

//globalObject.js
var globalObject = function() {

}

//init.js
globalObject.prototype.init = function() {
    this.utilityFunction();
    //do something with utilityObject1
    this.utilityFunction(this.utilityObject1);
}

//utilityFunction.js
globalObject.prototype.utilityFunction= function() {}

//utilityObject1.js
globalObject.prototype.utilityObject1 = {};

//main.js
var myObject = new globalObject();
myObject.init();

You could then overwrite the function by doing something like this: 然后,您可以通过执行以下操作来覆盖该函数:

//main.js
var myObject = new globalObject();
myObject.utilityFunction = function() {
    //new function
}
myObject.init(); // This will then use the new utilityFunction method you just set.

As I understand it, you want to have some lexical variables that all of your modules close over, but you want to keep the code for the various modules in different files. 据我所知,你想要一些词法变量,你的所有模块都关闭,但你想将各种模块的代码保存在不同的文件中。

One way to achieve this exact behavior is to create a single Javascript file by concatenating the module definitions together: 实现此确切行为的一种方法是通过将模块定义连接在一起来创建单个Javascript文件:

Header.js-partial Header.js偏

var myObject = (function(){
    var mainObjectList = [];
    var globalObject = {
            init:function(mainObjectId){

Logger.js: Logger.js:

function Logger() { this.enabled = true; }
Logger.prototype.log = function() {
  if (window.console && window.console.log) {
     return window.console.log.apply(window.console.log, arguments]);
  }
}

etc. 等等

Add other module files as desired. 根据需要添加其他模块文件。 They can reference lexical variables. 他们可以参考词汇变量。

Footer.js-partial Footer.js偏

    }// end init
}; // end globalObject
return globalObject;

})(); })();

In the end you need a script that will concatenate all of these files together into a single js file. 最后,您需要一个脚本,将所有这些文件连接成一个单独的js文件。 There is no other way to get truly lexical variable access in pure Javascript. 没有其他方法可以在纯Javascript中获得真正的词法变量访问。

A superior alternative 一个更好的选择

That said, this technique is ripe for confusion and I don't recommend it. 也就是说,这种技术很容易混淆,我不推荐它。 Closures are generally meant for closing over local variables, not program-wide variables. 闭包通常用于关闭局部变量,而不是程序范围的变量。 If you use a lexical variables declared 1000 lines ago, you will spend some amount of time tracking down where all your variables were declared when running your program. 如果你使用1000行之前声明的词法变量,你将花费一些时间来追踪运行程序时声明所有变量的位置。 Instead you should probably enclose private, 'global' data in the globalObject . 相反,您应该在globalObject包含私有的“全局”数据。 For example, store mainObjectList in globalObject.mainObjectList and reference that in module files. 例如,将mainObjectList存储在globalObject.mainObjectList并在模块文件中引用它。

I recommend a solution like that described by nemophrost. 我推荐像nemophrost描述的解决方案。 Each file should be valid javascript on its own. 每个文件都应该是有效的javascript。

You could use command-line PHP to serve as a preprocessor to combine your files. 您可以使用命令行PHP作为预处理器来组合您的文件。 For example, main.js.php could look like this: 例如, main.js.php可能如下所示:

(function() {
    <?php require('foo.js.php');?>
})();

and then run the command php main.js.php > combined.js when you want to produce an output file usable for minification and deployment. 然后运行命令php main.js.php > combined.js ,以便生成可用于缩小和部署的输出文件。

This has the advantage that you can load main.js.php onto a server to test a new version of the code without recompiling . 这样做的好处是,您可以将main.js.php加载到服务器上,以测试新版本的代码,而无需重新编译 You can just put a line at the very beginning of main.js.php to get PHP to send the correct MIME type: 你可以在main.js.php的最开头加一行来让PHP发送正确的MIME类型:

<?php header('Content-type: text/javascript');?>

The way I deal with this problem to check to see if the global object exists and if not create it. 我处理这个问题的方法是检查全局对象是否存在,如果不存在则创建它。 This way the order isn't important. 这样顺序并不重要。

// file 1
var Global_Obj = Global_Obj || {};  // creates empty global object
Global_Obj.An_Obj = { /* stuff */ };

// file 2
var Global_Obj = Global_Obj || {}; // uses created global object
Global_Obj.Another_Obj = { /* stuff */ };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在同一页面上显示多个(但单独的)JSON请求 - How can I display multiple (but seperate) JSON requests on the same page 高图-如何通过不同的报告获得单独的图例? - Highmaps - how i can have a seperate legend by different report? 如何在同一HTML页面上的三种不同形式下验证同一字段 - How can I validate the same field under three different forms on the same html page 如何将JavaScript函数应用于同一类下的多个不同元素(结果不同)? - How can I apply JavaScript function to several different elements under the same class (with different results)? 如何将猫鼬子文档分成单独的文件? - How can I separate mongoose subdocument into seperate files? 如何将 websocket/express 服务器分成不同的文件? - How to seperate websocket/express server into different files? 如何将一个闭包从外部函数中分解出来以在不同的上下文中重用所述闭包? - How can I factor a closure out of an outer function to reuse said closure in different contexts? 如何在Meteor应用中以不同的名称发布同一收藏集? - How can i publish the same collection under different names in a Meteor app? 如何将Socket.io路由代码分成不同的文件 - How do I seperate Socket.io route code into different files 如何在具有不同 CSS 的不同文件中多次使用相同的组件 - How can i use same component multiple time in different files with different CSS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM