我可以在“窗口”以外的上下文中加载 JavaScript 文件吗?
我尝试加载一些外部 .js 文件,并遇到一些无法解决的命名空间冲突。
我的想法是以某种方式在自己的上下文中加载一些文件,将指向窗口对象的“this
”替换为某个自定义名称空间。
例如:
first.js:
name = "first";
second.js:
name = "second";
在我看来,这种技巧非常有用。有可能吗?
编辑
似乎替换“this
”并不能解决问题,因为它不是 javascript 中标识符解析的默认上下文。这是我的测试代码:
var first = {};
var second = {};
(function(){name = "first";}).call(first);
(function(){name = "second";}).call(second);
document.write('name= '+name+' <br/>\n'); //prints "second"
document.write('first.name= '+first.name+' <br/>\n'); //prints "undefined"
document.write('second.name= '+second.name+' <br/>\n'); //prints "undefined
有什么想法吗?
解决方案
这是不可能的。结果我比今天早上更聪明,所以我放弃了。 我向任何有类似问题并可能想要解决这个问题的人推荐这些具有启发性的阅读材料: http://jibbering.com/faq/notes/closures/
http://softwareas.com/cross-domain-communication-with-iframes
I try to load some external .js files, and have some irresolvable namespace conflicts.
I had the idea of loading some of the files in their own context somehow, replacing the "this
" from pointing at the window object to some custom namespace.
example:
first.js:
name = "first";
second.js:
name = "second";
It seems to me that this kind of trick can be very useful. Is it possible at all?
EDIT
seems that replacing "this
" does not begin to solve the problem, as it is not the default context for identifier resolution in javascript. this is my test code:
var first = {};
var second = {};
(function(){name = "first";}).call(first);
(function(){name = "second";}).call(second);
document.write('name= '+name+' <br/>\n'); //prints "second"
document.write('first.name= '+first.name+' <br/>\n'); //prints "undefined"
document.write('second.name= '+second.name+' <br/>\n'); //prints "undefined
any ideas?
RESOLUTION
It is not possible. I ended up wiser than I was this morning, and I gave it up.
I recommend these enlightening reading materials for anyone with a similar problem that might want to take a crack at it:
http://jibbering.com/faq/notes/closures/
http://softwareas.com/cross-domain-communication-with-iframes
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我的一个想法是,在不需要修改外部 JavaScript 文件的情况下,以 AJAXy 方式获取 JavaScript 文件的内容(取决于你如何做到这一点),然后使用
new Function(code)
方式,然后用new
初始化它:那么
surrogateWindow
就是该代码的this
。我认为这个想法应该可行。One idea I've had for doing it without needing modifications to your external JavaScript file is getting the contents of the JavaScript file in an AJAXy way (up to you how you do that) and then put it all in a function using the
new Function(code)
way, then initialise that withnew
:Then
surrogateWindow
is thethis
of that code. I think that that idea should work.我不清楚你这样做的原因;你到底用
this
做什么?将 secondary.js 的内容包装在匿名函数中将防止该文件中的变量与全局变量发生冲突。如果您确实必须将
this
设置为非全局对象的特定对象,那么您可以执行类似UPDATE
的操作,但您无法执行您想要的操作。您似乎想要访问 Variable 对象,它是在 JavaScript 中声明变量时添加属性的对象。在全局代码中,Variable对象是全局对象,因此可以访问它;在函数中,这是执行上下文的一个属性,无法直接访问。
I'm not clear on your reason for doing this; what are you using
this
for, exactly?Wrapping the contents of your second.js in an anonymous function will prevent variables in that file from conflicting with global variables. If you really must have a
this
set to a particular object that isn't the global object, you could do something likeUPDATE
You can't do what you want. You seem to want to access the Variable object, which is the object to which a property is added when you declare a variable in JavaScript. In global code, the Variable object is the global object, so you can access it; within a function this is a property of the execution context that there is no way to access directly.
尽管这是一个老问题,但这个答案可能仍然与某些人相关:
加载 js 文件时,它会自动获取窗口的上下文。这是不可能改变的。
但是,如果您试图避免正在加载的库之间发生冲突,并且您无法控制这些库,并且它们没有内置的“无冲突”机制,那么有一个不错的技巧-
您可以将它们加载到无源 iframe 中。
这将使它们的上下文成为 iframe 的窗口,并且您仍然可以访问 iframe,因为这里不存在跨域问题。
您可以查看此库作为使用此技术的示例。
Even though this is an old question, this answer may still be relevant for some:
When a js file is loaded it automatically gets the window's context. That is not possible to change.
However, if you are trying to avoid conflicts between libraries that you are loading, and you don't have control over those libs, and they don't have a built-in "no-conflict" mechanism, then there is a nice trick -
you can load those into a source-less iframe.
This will make their context to be the window of the iframe, and you will still be able to access the iframe since there is no cross-domain issue here.
You can see this library as an example for use of this technique.
您可以在
iframe
中加载文件,该文件不是.js
而是 HTML 文件,例如:技巧是使用
parent.
> 获取父页面中可用的 javascript 对象。You can load your file in an
iframe
, the file is not a.js
but an HTML file, like:The trick is to use
parent.
to get the javascript objects available in the parent page.对于您编写的代码,我认为您误解了 JavaScript 中类的一些工作方式。在 Java 中,您可以删除
this.
,但在 JavaScript 中则不能。您始终需要有this.
。那么你的代码就变成了:以更正常的类方式来完成它也很好。我不确定你的具体情况是什么,因为我看不到你的所有代码,所以你可能已经在这样做了。
For the code you've written, I think you're misunderstanding some of the way classes work in JavaScript. In Java you can drop the
this.
, but in JavaScript you can't. You'll always need to havethis.
there. So then your code becomes:It would also be good to do it in a more normal class way. I'm not sure exactly what your situation is as I can't see all your code so you might be already doing it this way.
好吧,你可以用这样的东西包装 js 文件的内容:
Well you could wrap the contents of the js files with something like this: