я могу загрузить файл JavaScript в контексте, отличном от «окна»? - PullRequest
5 голосов
/ 08 ноября 2010

Я пытаюсь загрузить некоторые внешние файлы .js, и у меня возникают неразрешимые конфликты пространства имен.

У меня была идея как-то загрузить некоторые файлы в их собственном контексте, заменив «this» с указанием на объект окна на какое-то пользовательское пространство имен.

пример:

first.js:

name = "first";

second.js:

name = "second";

Мне кажется, что этот вид уловки может быть очень полезным. Возможно ли это вообще?

EDIT
кажется, что замена «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

Ответы [ 6 ]

3 голосов
/ 08 ноября 2010

Мне непонятно, по какой причине вы это сделали;для чего вы точно используете this

Оборачивание содержимого вашего second.js в анонимную функцию предотвратит конфликт в этом файле с глобальными переменными.Если вам действительно нужно установить this для определенного объекта, который не является глобальным объектом, вы можете сделать что-то вроде

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

ОБНОВЛЕНИЕ

Выне могу делать то, что ты хочешь.Похоже, вы хотите получить доступ к Переменному объекту , который является объектом, к которому добавляется свойство при объявлении переменной в JavaScript.В глобальном коде объект Variable является глобальным объектом, поэтому вы можете получить к нему доступ;внутри функции это свойство контекста выполнения, к которому нет прямого доступа.

2 голосов
/ 30 июня 2014

Несмотря на то, что это старый вопрос, для некоторых этот ответ может быть актуален:

Когда файл js загружен, он автоматически получает контекст окна. Это невозможно изменить. Однако, если вы пытаетесь избежать конфликтов между библиотеками, которые вы загружаете, и у вас нет контроля над этими библиотеками, и у них нет встроенного механизма «без конфликтов», то есть хороший прием. - Вы можете загрузить их в iframe без исходного кода. Это сделает их контекст окном iframe, и вы все равно сможете получить доступ к iframe, поскольку здесь нет междоменной проблемы.

Вы можете увидеть эту библиотеку в качестве примера использования этой техники.

2 голосов
/ 08 ноября 2010

Одна идея, которая у меня возникла, чтобы сделать это без необходимости изменения внешнего файла JavaScript, - это получить содержимое файла JavaScript AJAXy-способом (до вас, как вы это делаете), а затем поместить все это в функцию, используя new Function(code), затем инициализируйте его с помощью new:

surrogateWindow = new new Function(jsCode)();

Тогда surrogateWindow - это this этого кода. Я думаю , что эта идея должна работать.

1 голос
/ 08 ноября 2010

Для кода, который вы написали, я думаю, вы неправильно понимаете, как классы работают в 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"

Было бы также хорошо сделать это более обычным способом.Я точно не знаю, какова ваша ситуация, поскольку я не вижу весь ваш код, так что вы, возможно, уже делаете это таким образом.

1 голос
/ 08 ноября 2010

Вы можете загрузить свой файл в iframe, файл является не .js, а 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объекты, доступные на родительской странице.

0 голосов
/ 08 ноября 2010

Хорошо, вы можете обернуть содержимое файлов js примерно так:

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

  //this should refer to the current anonymous function, and not the window object
  return this;
})();
...