2010-08-08 6 views
-1
for (var i in variables) { 
    eval('var ' + i + ' = variables[i]'); 
} 

В принципе, я хочу передать переменные свойства локальных переменных.Как сделать это без Eval()

Есть ли альтернатива использованию Eval()

Или какая из них лучше:

1.

var _ = variables; 
for (var i = 0; i < 100000; i++) { 
    _.test1(); 
    _.test2(); 
    _.test3(); 
} 

2.

with (variables) { 
    for (var i = 0; i < 100000; i++) { 
     test1(); 
     test2(); 
     test3(); 
    } 
} 

3.

var test1 = variables.test1, 
    test2 = variables.test2, 
    test3 = variables.test3; 
for (var i = 0; i < 100000; i++) { 
    test1(); 
    test2(); 
    test3(); 
} 

4.

for (var i in variables) eval('var ' + i + ' = variables[i]'); 
for (var i = 0; i < 100000; i++) { 
    test1(); 
    test2(); 
    test3(); 
} 
+8

Почему бы вам не сделать это? –

+0

Если «переменные» действительно длинны, например: namespace.constructors.blah.dramatic.variables , а на содержимое переменных много ссылок, тогда полезно иметь его содержимое в локальных переменных. Можно использовать ключевое слово «с», но у него есть свои проблемы. пример прост для упрощения. –

+0

Вам следует избегать использования 'eval()' util, вы знаете JS достаточно хорошо, чтобы знать, когда абсолютно необходимо использовать его, потому что его медленный и его использование обычно считается плохой практикой. – xj9

ответ

0

Ну, я сам отправлю ответ.

No.

Там нет никакого способа установить локальные переменные, не зная имя переменной без использования Eval() ...

... Но используя локальные переменные (вариант 3) - лучший способ.

4

Глядя на ваш comment кажется, что ваш основной проблемой является необходимость ссылаться несколько раз глубоко вложенный объект, избегая eval и with Я бы просто рекомендовал вам использовать идентификатор псевдонима, например:

// some local scope... 
var foo = namespace.constructors.blah.dramatic.variables; 
// replace foo with something meaningful :) 
foo.method1(); 
foo.method2(); 
foo.property1; 
// etc... 

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

+0

Спасибо. Я считал это, конечно. Но, учитывая, что имена переменных известны; вместо использования псевдонима я бы просто повторил то, что делает eval. Например, var a = variables.a; var b = variables.b; и т. д. ... Я считаю, что это самый эффективный метод, но не такой элегантный, как хотелось бы. eval сохраняет несколько байтов, но выглядит как хак. Установка дюжины переменных с eval не должна быть заметной. –

+3

@ Карлос Гил Сохранение «байтов» - это бесполезная работа. Если вы хотите оптимизировать свой код, уменьшив поиск цепочки областей, то, что у @CMS есть, есть путь. Кроме того, 'eval' (а иногда и' with') медленный, и побочные эффекты неправильного использования 'with' делают его нецелесообразным. –

+0

@ Justin Johnson Я абсолютно уверен, что после первоначальной установки локальных переменных они получают доступ быстрее, чем свойства одного из них. Имея в виду; foo * доступны быстрее, чем foo.property *. Если я ошибаюсь, объясните. –

0

Один из вариантов - сделать объект текущей областью. Он не будет делать от свойств локальных переменных, но вы можете получить доступ к ним, используя ключевое слово this:

var variables = { a:42, b:1337 }; 

(function(){ 
    alert(this.a); 
    alert(this.b); 
}).apply(variables); 

Это имеет то преимущество, что вы ничего не копируете в любом месте, вы обращаетесь свойства напрямую.

+1

Как это может быть лучше, чем просто присвоить 'variables' более короткое имя. Вы все равно будете обращаться к свойствам напрямую. – MooGoo

+0

@MooGoo: Нет, если вы скопируете свойства в локальные переменные, вы не будете обращаться к свойствам напрямую. Если вы измените локальную переменную, свойство не изменится. – Guffa

+0

Я сказал «присваивание« переменным »более короткого имени», т. Е. «Var v = variables». 'v' содержит ссылку на тот же объект, что ссылки' variables', которые не отличаются от 'this', содержащего эту ссылку, за исключением того, что она более краткий и не требует ненужного вызова функции (что, вероятно, является медленным, если не медленнее, чем используя 'with'). – MooGoo