7

我尝试加载一些外部 .js 文件,并且有一些无法解决的命名空间冲突。

我想以某种方式在它们自己的上下文中加载一些文件,将“ this”从指向窗口对象替换为一些自定义命名空间。

例子:

第一个.js:

name = "first";

第二个.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-带 iframe

4

6 回答 6

3

我不清楚你这样做的原因;你到底在用this什么?

将 second.js 的内容包装在匿名函数中将防止该文件中的变量与全局变量发生冲突。如果你真的必须有一个this不是全局对象的特定对象的集合,你可以做类似的事情

var differentThis = {};
(function() {
    // Contents of second.js go here
}).call(differentThis);

更新

你不能做你想做的事。您似乎想要访问Variable object,这是在 JavaScript 中声明变量时添加属性的对象。在全局代码中,Variable 对象是全局对象,所以你可以访问它;在函数中,这是执行上下文的一个属性,无法直接访问。

于 2010-11-08T10:50:59.283 回答
3

我在不需要修改外部 JavaScript 文件的情况下这样做的一个想法是以 AJAXy 方式获取 JavaScript 文件的内容(取决于你如何做到这一点),然后使用这种new Function(code)方式将其全部放入一个函数中,然后初始化new

surrogateWindow = new new Function(jsCode)();

然后surrogateWindowthis那个代码。我认为这个想法应该奏效。

于 2010-11-08T11:46:14.447 回答
2

尽管这是一个老问题,但这个答案可能仍然与某些人相关:

加载 js 文件时,它会自动获取窗口的上下文。这是不可能改变的。但是,如果您试图避免正在加载的库之间的冲突,并且您无法控制这些库,并且它们没有内置的“无冲突”机制,那么有一个不错的技巧- 您可以将它们加载到无源 iframe 中。这将使它们的上下文成为 iframe 的窗口,并且您仍然可以访问 iframe,因为这里没有跨域问题。

您可以将此库视为使用此技术的示例。

于 2014-06-30T12:14:57.547 回答
1

您可以在 中加载文件iframe,该文件不是.jsHTML 文件,而是 HTML 文件,例如:

<html>
<body>
  <script>
    var $ = parent.$, // you can share objects with the parent, eg: jQuery
      localObject = { // your local object definition
        name: 'first',
        showName: function(){
          $('div.name').html( this.name );
        }
      };
    //assign the local object to the custom namespace
    parent.customNamespace.object1 = localObject; 
  </script>
</body>
</html>

诀窍是用来parent.获取父页面中可用的 javascript 对象。

于 2010-11-08T09:00:04.470 回答
1

对于您编写的代码,我认为您误解了 JavaScript 中类的某些工作方式。在 Java 中你可以删除this.,但在 JavaScript 中你不能。你总是需要在this.那里。那么你的代码就变成了:

var first = {};
var second = {};

(function(){this.name = "first";}).call(first);
(function(){this.name = "second";}).call(second);


document.write('name= '+name+' <br/>\n'); //prints "undefined"
document.write('first.name= '+first.name+' <br/>\n'); //prints "first"
document.write('second.name= '+second.name+' <br/>\n'); //prints "second"

以更正常的课堂方式进行也很好。我不确定您的具体情况是什么,因为我看不到您的所有代码,所以您可能已经在这样做了。

function Something(name) {
    this.name = name;
}

var first = new Something("first");
var second = new Something("second");

document.write('name= '+name+' <br/>\n'); //prints "undefined"
document.write('first.name= '+first.name+' <br/>\n'); //prints "first"
document.write('second.name= '+second.name+' <br/>\n'); //prints "second"
于 2010-11-08T11:52:18.050 回答
-1

好吧,您可以使用以下内容包装 js 文件的内容:

var externalInterfaceForYourObject = (function(){
  //code that defines your object

  //this should refer to the current anonymous function, and not the window object
  return this;
})();
于 2010-11-08T08:28:21.667 回答