2010-02-11 12 views
0

Является ли следующее возможным:изменить глобальную область видимости функции в JavaScript

var someObject = {someProperty : "someValue"}; 
var someFunction = function() { 
someProperty = "anotherValue"; 
}; 

// what do I do here, in order to use 
// someFunction to change someObject, 
// without altering either of those things? 

// directly accessing "someObject" in someFunction 
// is not an option. e.g., none of this: 
/* 
    var someFunction = function() { 
     someObject.someProperty = "anotherValue"; 
    }; 
*/ 

if(someObject.someProperty=="anotherValue") alert("Hooray!"); 

?

Если нет в стандартном JavaScript, возможно ли это в JavaScript Mozilla для расширения Firefox?

Спасибо.

+0

Я вижу, что вы упоминали GreaseMonkey в некоторых комментариях. Обратите внимание, что сценарии GreaseMonkey работают в изолированной среде с различным поведением, чем запуск скрипта прямо в браузере. http://wiki.greasespot.net/Greasemonkey_Manual:Environment http://wiki.greasespot.net/Global_object – z5h

+0

Я не пишу этот код для Greasemonkey. Я написал, что работает под расширением Firefox. Также я хорошо знаю о песочной природе GM, и именно поэтому я пытаюсь воспроизвести ее здесь. –

ответ

1

Для тех, кому может быть интересно, самое близкое, что я нашел, это Components.utils.evalInSandbox. Это определенно не идеально, но легко лучшее для этой проблемы.

+0

Конечно, любой код, который вы пишете, не очень портативный JavaScript. Я вижу, что в вашем профиле вы разрабатываете множество сценариев GreaseMonkey, и поэтому, вероятно, привыкли к такому поведению. Моя рекомендация - перейти от вашей зоны комфорта и сделать что-то более универсальным способом JavaScript. Я бы рекомендовал большую часть работы Дугласа Крокфорда как источник знаний/вдохновения. Это всего лишь мои 2 цента. – z5h

+0

Мне лично не нужно писать таким образом. Я разрабатываю надстройку, которая будет очень полезной для других, которые будут писать для них скрипты. Как вы можете сказать, это первый раз, когда я действительно прыгаю в разработку аддона. Не ставьте нам пользователей. Мы не глупые костяшки, которые не знают, что мы делаем. ;) Что касается портативного устройства: вы имеете в виду, как в нем, его можно использовать везде? Я огромный фанат Firefox, и мне все равно, что он используется где-то еще. Конечно, Google Chrome работает быстро, но его супер заблокирован и бесполезен. –

+0

Я сказал, что это мои 2 цента, потому что я хотел быть ясным, что я не слишком сильно налагал свою точку зрения. Сказав это, все на этой странице говорят, что это невозможно. То, что они на самом деле имеют в виду, они не считают, что это стоит того. Если вы действительно этого хотите, вы можете реализовать свой собственный язык в JavaScript с любой семантикой, которую хотите. Вот генератор парсера/лексера для JS в JS, чтобы вы начали. http://jscc.jmksf.com/ – z5h

0

Нет, вы не можете.

var someFunction = function() { 
    someProperty = "anotherValue"; 
}; 

Здесь someProperty - это глобальная переменная (созданная, если ее не было ранее).

var someObject = {someProperty : "someValue"}; 

Здесь someProperty является ключом объекта (а не переменной).

Итак, в каждом контексте токен someProperty относится к чему-то другому и полностью независимым.

Невозможно изменить функцию объекта без прямой ссылки/вызова другой функции.

+0

Я понимаю разницу между ключом и переменной. Неужели это невозможно? Я знаю, что разработчики Greasemonkey сделали это как-то, но их исходный код - беспорядок. –

+0

Лучшее, что вы можете получить, не изменяя свой код, - это ответ @Phil Ross, в котором «это» является ссылкой на объект, но, как я уже сказал, вам всегда нужна такая ссылка так или иначе. – Johnco

0
eval("someObject.someProperty='anotherValue'"); 

Будет ли это работать? Что вы считаете «прямым доступом к someObject» в someFunction? » Вы будете иметь доступ к SomeObject каким-то образом, если вы хотите изменить свою собственность ...

+0

Под этим я имею в виду буквально печатать «someObject». в некоторой функции. Я хочу, чтобы код работал, как он появляется. –

0

Если вы готовы изменить вашу функцию, чтобы ссылаться на this.someProperty вместо просто someProperty, то вы можете использовать apply или call:

var someFunction = function() { 
    this.someProperty = "anotherValue"; 
}; 

someFunction.apply(someObject); 
+0

Я хочу использовать что-то другое, кроме "apply". Идея состоит в том, чтобы иметь возможность свободно вводить код в функцию, не беспокоясь об этом. или "someObject." –

0

Нет. Это все о области (области) и свойствах.

Когда вы говорите someObject = ... или someobject.whatever, то, что вы говорите, дает мне someObject в ближайшем объеме, а затем что-то с этим делать.

Scopes гнездо. Функции создают новую область и захватывают окружающую область. Переменные в более близких областях могут изменять переменные в окружающих областях. Ваша функция может видеть все в области, в которой она была заявлена, поэтому она может видеть someObject.

someProperty является частью пары ключ/значение в someObject. Ничто не доходит до него, не пройдя someObject и попросив его вернуть значение, сохраненное с помощью клавиши someProperty.

+0

Собственно, someObject находится в области «окна», как и каждый «глобальный» объект. Точка - это изменение основного объекта из «окна» в «someObject». –

1

Для чисто академических целей, вот так:

with (someObject) { 
    eval('(' +someFunction.toString() + ')();'); 
} 

Не используйте это в производственной среде!

[Изменить]: Чтобы уточнить, вот как вы его используете.

var someObject = {someProperty : "someValue"}; 
var someFunction = function() { 
someProperty = "anotherValue"; 
}; 

with (someObject) { 
    eval('(' +someFunction.toString() + ')();'); 
} 

if(someObject.someProperty=="anotherValue") alert("Hooray!"); 

Это НЕ относятся к SomeObject внутри SomeFunction.

+0

Это относится к «someObject» внутри тела функции. Суть заключается в том, чтобы найти способ не делать этого. –

+0

Ваш вопрос не упоминает об этом. Вы говорите, что не можете изменять «someObject» или «someFunction», и вы не можете ссылаться на 'someObject' _inside_' someFunction'. Этот подход не делает. –

+0

Я предполагаю, что это так, но использует «с» и «eval», две из последних вещей, которые кто-то хотел бы использовать. Я надеялся на какое-то умное использование «apply»/«call», чтобы это разрешить, но я думаю, что это просто невозможно. –

0
var someObject = {someProperty : "someValue"}; 
with (someObject) 
{ 
    window.someFunction = function() { 
    someProperty = "anotherValue"; 
    }; 
} 

if(someObject.someProperty=="anotherValue") alert("Hooray!"); 

Не лучшая практика кодирования, но должна выполнять то, что вы хотите.

Смежные вопросы