Javascript объявить локальную переменную - PullRequest
8 голосов
/ 13 июля 2009

По сути, это вопрос, как получить доступ к локальному обработчику области видимости. Я пытаюсь добиться чего-то похожего для определения глобальной переменной, например:

window['newObject'] = "some string";
alert(newObject);

но для локального охвата. Прямо сейчас единственное решение, которое у меня есть, использует evals:

eval("var newObject='some string'");

Но это действительно уродливое решение ... Лучше всего было бы использовать ссылку на локальную область видимости, как в окне [], но я никогда не слышал о какой-либо ссылке на локальную область видимости ... Есть идеи? *

Пример идет здесь:

function x(arg)
{
   localScope[arg.name]=arg.value;
   alert(sex);
}

x({name:"sex", value:"Male"});

Ответы [ 8 ]

6 голосов
/ 13 июля 2009

То, что вы ищете, называется объектом вызова . Но согласно этому , вы не можете получить к нему прямой доступ, поэтому вам не повезло.

1 голос
/ 01 марта 2010

Не уверен, что именно вам нужно, но вот мои 2 цента.

Единственный способ динамически создавать переменные в существующей функции - это метод eval, который вы уже упомянули.

Другой вариант (упомянутый другими) заключается в том, что ваша функция берет контекстную карту, а шаблон обращается к ней с точечной нотацией (context.var1)

Мое последнее предложение - конструктор функций. Но я чувствую, что это может быть то, что вы ищете. (Обратите внимание, что конструктор функции страдает от тех же проблем, что и вызов eval)

var arg1 = "first";
var arg2 = "last";

// This is the body of the function that you want to execute with first
// and last as local variables. It would come from your template
var functionBody = "alert(first + ' ' + last)";

var myCustomFun = new Function(arg1, arg2,  functionBody);

myCustomFun("Mark", "Brown"); // brings up and alert saying "Mark Brown";

Надеюсь, это поможет

1 голос
/ 13 июля 2009

Вы можете попробовать трюк с именованными аргументами
РЕДАКТИРОВАТЬ: Это не кросс-браузер

function x( {sex:sex, height:height} ) {
    alert( sex );
    alert( height );
}

x( { sex: 'male', height: 'short' } );
x( { height: 'medium', sex: 'female' } );

// male
// short
// female
// medium
1 голос
/ 13 июля 2009

Окей, я нашел связанный вопрос, который говорит о том, что мне нужно ...

Как я могу динамически получить доступ к локальной области в Javascript?

Я просто помню, что в ECMA 262 есть только один способ добавления динамически локальных переменных в область видимости с помощью оператора with (и, конечно, eval), вот решение:

var x=function(obj)
{

    with(obj) 
    {
       alert(someObj);
    }
 }
 alert(typeof someObj);


 x ( {someObj:"yea"}) ;

 alert(typeof someObj);
1 голос
/ 13 июля 2009

Почему бы не создать объект в локальной области, а затем использовать его в качестве контейнера для любых переменных, которые вы хотите создать динамически?

function x(arg)
{
    var localSpace = {};
    localSpace[arg.name] = arg.value;
}
1 голос
/ 13 июля 2009

Я должен что-то упустить. Чем то, что вы хотите, отличается от простого:

 var newObject = 'some string';

? (ОП уточнил вопрос)

Я не думаю, что есть способ сделать то, что вы просите. Использовать элементы локального объекта, например

function doSomething(name, value)
{
  var X = {};
  X[name] = value;
  if (X.foo == 26)
    alert("you apparently just called doSomething('foo',26)");
}

Если вы выберете 1-символьную переменную, такую ​​как $ или X, она «будет стоить» вам 2 символа (имя переменной плюс точка) и позволит избежать попыток использовать eval или сделать что-то странное.

0 голосов
/ 13 июля 2009

Я не совсем уверен, что понимаю ваш вопрос. При создании класса x я обычно делаю это:

function x(args) {
  var _self = this;

  _self.PriviledgedMethod(a) {
      // some code
  }

  function privateMethod(a) {
      // some code
  }
}

var newObject = new x(args);

Вы можете продолжить получать доступ к _self и args, поскольку он закрыт закрытыми функциями.

0 голосов
/ 13 июля 2009

Интересный вопрос, никогда не задумывался о чем-то подобном. Но каков вариант использования?

Причина, по которой вы захотите сделать что-то подобное, заключается в том, что вы не знаете имя переменной. Но тогда в этом случае единственным способом снова получить доступ к переменной будет использование того же ссылочного объекта. То есть Вы можете просто использовать любой старый объект для хранения данных.

Чтение из такого эталонного объекта было бы интересно для целей отладки, но я не понимаю, зачем вам писать в него.

Edit:

Пример, который вы опубликовали, не убеждает меня в необходимости доступа к локальной области, поскольку у вас по-прежнему жестко задано имя sex в предупреждении. Это может быть реализовано как:

function x(arg)
{
  container = {};
  container[arg.name] = arg.value;
  alert(container.sex);
}

Не могли бы вы подробнее остановиться на примере?

...