我注意到,在我的团队升级到Dojo 1.8之后,我正在为项目工作的一些遗留脚本不再工作了。具体来说,他们创建的全局变量不再被创建。
我挖了一遍,发现Dojo 1.8团队非常反对全局变量。事实上,如此反对,他们认为用户在物理上不可能在需要的末尾使用以下代码在必需的脚本中创建全局变量:
req.eval =
function(text, hint){
return eval_(text + "\r\n////@ sourceURL=" + hint);
};
var eval_ = new Function('return eval(arguments[0]);');
这很棒,但是我正在使用的旧代码无法更改,所以我一直试图弄清楚如何解决这个问题并在本地环境中执行eval。
幸运的是,dojo.eval
仍然来自旧版本的Dojo,这就是我想要的。因此,我只需要访问req.eval
并在某些情况下将功能更改为return dojo.eval(...)
甚至只更改eval(...)
。
问题是,我无法弄清楚如何访问req
。这是发生的事情:
我在HTML文件顶部的脚本标记中包含dojo.js
。它加载在自己的脚本文件中。
dojo.require
可以从我自己的文件中访问。它在脚本文件中用define
定义:
'dojo/_base/loader':function(){
define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
我不确定这是否重要。无论如何,在dojo.require
的范围内,我可以看到一个叫injectModule
的东西,而在我自己的文件中我不能。 injectModule
是一个局部变量,因此您无法使用this
查看它。它在文件开头的匿名函数中定义,即
(function(){ ... injectModule = function(){} ... })();
在injectModule
函数中,有以下行:
req.getText(url, legacyMode!=sync, xhrCallback);
转到req.eval
。因此injectModule
可以看到req
。
我不知道该怎么做。我的邪恶JavaScript技巧都没有帮助我开始浏览这个范围的僵局。一个好的开始是弄清楚如何从我调用injectModule
的外部脚本文件中查看dojo.require
。但是,我无法使用'bind'来执行此操作,因为它是匿名函数中定义的局部变量。这甚至可能吗?
为了让事情变得更容易,以下是摘要:
文件1:
<script src="dojo.js"></script>
dojo.require(File 3);
console.log(globalVar);
文件2:
(function(){req.eval = unhelpful function})();
define(["require"], function(module){
dojo.require = function(x){req.eval(x)}
});
文件3:
globalVar = ...;
我可以修改文件1和3,但文件3总是需要一个全局变量。我无法修改文件2.目标是将文件2中的req.eval
更改为更好的功能。
之前声明全局变量不起作用,因为范围更改意味着文件3仍然无法看到它。
反射和字符串替换不起作用,因为范围错误并且JS在服务器端缩小。
覆盖文件1中的方法不起作用,因为我看不到范围。
使用JavaScript bind
功能也毫无结果。
答案 0 :(得分:3)
为此,dojo创建了dojo.global
。它将指向已加载dojo的window
(适用于框架布局)。
所以声明你的全局变量如下:
require([ "dojo/_base/kernel", ... ] , function(kernel) {
kernel.global.globalVariable = 1;
console.log('set')
})
dojo.addOnLoad(function() {console.log('get', globalVariable);});
答案 1 :(得分:2)
可以通过全局window
对象访问全局范围,因此window.foo = 'bar'
与创建全局变量foo
相同。有关详细信息,请访问:https://stackoverflow.com/a/4862268/168382