[英]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文件:
var myObject = (function(){
var mainObjectList = [];
var globalObject = {
init:function(mainObjectId){
function Logger() { this.enabled = true; }
Logger.prototype.log = function() {
if (window.console && window.console.log) {
return window.console.log.apply(window.console.log, arguments]);
}
}
Add other module files as desired. 根据需要添加其他模块文件。 They can reference lexical variables.
他们可以参考词汇变量。
}// 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中获得真正的词法变量访问。
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.