Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.07.2014, 11:59
foo foo вне форума
Профессор
Отправить личное сообщение для foo Посмотреть профиль Найти все сообщения от foo
 
Регистрация: 17.05.2014
Сообщений: 197

В чем сходство Function и Eval?
У крокфорда в good parts есть утверждение, что Function -- это, почти то же самое что eval. Я копаюсь уже битый час, и не могу понять вообще, что у них общего. Насколько я понял, Function сразу компилируется в обычную анонимную ф-цию. И в дальнейшем, она ведет себя как обычная ф-ция, даже с сохранением лексического скопа в замыканиях.
Код:
fu=Function("var a=1; return function(){return(a)}")
console.log(""+fu)
//
//out:
//function anonymous() {
//var a=1; return function(){return(a)}
//}

inner_fu=fu()
console.log(inner_fu())
//out:
//1
Что же общего нашел крокфорд между ними? Покажите пример эквивалентного поведения, пожалуйста.
Ответить с цитированием
  #2 (permalink)  
Старый 06.07.2014, 12:27
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Общее то, что они работают со строками, т.е. компилируют строки в JS. Function всегда создаёт глобальные функции, т.е.

var a = 1;

(function () {
    var a = 2;
    new Function('alert(a)')(); // 1
})();


A eval работает в том контексте, в котором он был вызван.

var a = 1;

(function () {
    var a = 2;
    eval('alert(a)'); // 2
})();


В 99% случаев лучше использовать Function, т.к. для такого кода также используется JIT компилятор VM, а вот для eval конструкций нет и это может серьёзно сказаться на производительности, а самое страшное то, что вызов eval внутри блока также отменяет использование JIT для всего блока:

// Очень быстрый цикл, т.к. используется JIT
for (var i = 0; i < 1e6; i++) {
    console.log(el);
}

// Всё будет очень тормозить, т.к. вызов eval внутри цикла отменил использование JIT для всей конструкции.
for (var i = 0; i < 1e6; i++) {
    eval('console.log(el);');
}
__________________
kobezzza
code monkey
Ответить с цитированием
  #3 (permalink)  
Старый 06.07.2014, 12:31
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Цитата:
Покажите пример эквивалентного поведения, пожалуйста.
// Парсинг строки как литерала объекта
var a = '({a: 1, b: 2})';

eval(a); // {a: 1, b: 2}

new Function('return ' + a)(); // {a: 1, b: 2}


// Создание функции из строки (однако следует помнить про то, что у функций будет разный контекст)

eval('(function (a, b) { return a + b; })')(1, 2) // 3

new Function('a', 'b', 'return a + b')(1, 2) // 3
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.07.2014 в 12:39.
Ответить с цитированием
  #4 (permalink)  
Старый 06.07.2014, 12:38
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,521

var a = '{a: 1, b: 2}';
 
eval(a); // {a: 1, b: 2}
kobezzza, ёшкин кот, этож классический пример.
eval(a); //syntax error
__________________
29375, 35
Ответить с цитированием
  #5 (permalink)  
Старый 06.07.2014, 12:40
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от Aetae Посмотреть сообщение
var a = '{a: 1, b: 2}';
 
eval(a); // {a: 1, b: 2}
kobezzza, ёшкин кот, этож классический пример.
eval(a); //syntax error
Поправил, вечно забываю про метки.
__________________
kobezzza
code monkey
Ответить с цитированием
  #6 (permalink)  
Старый 06.07.2014, 13:56
foo foo вне форума
Профессор
Отправить личное сообщение для foo Посмотреть профиль Найти все сообщения от foo
 
Регистрация: 17.05.2014
Сообщений: 197

Сообщение от kobezzza
В 99% случаев лучше использовать Function
Провел небольшой тестик на ноде, который мне дает основание усомниться:
Код:
test1=function(){
var i=1000000
while(i){
	a=Function("test")
	i--
}
}

test2=function(){
var i=1000000
while(i){
	a=function(){"test"}
	i--
}
}

console.time(1)
	test1()
console.timeEnd(1)

console.time(2)
	test2()
console.timeEnd(2)
1: 2133ms
2: 60ms
с эвалом даже получше дела обстоят:
Код:
a=1
test3=function(){
var i=1000000
while(i){
	a=eval("a")
	i--
}
}


console.time(3)
	test3()
console.timeEnd(3)
3: 1362ms

Последний раз редактировалось foo, 06.07.2014 в 14:02.
Ответить с цитированием
  #7 (permalink)  
Старый 06.07.2014, 14:01
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Цитата:
В 99% случаев лучше использовать Function
Ты троллишь чтоли? Я имел ввиду Function предпочтительнее eval в 99%.

Цитата:
Провел небольшой тестик на ноде, который мне дает основание усомниться.
Ну как бы очевидно, что компиляция в рантайме без предварительного кеширования априори медленее, т.к. бедная VM на каждой итерации должна поднимать транслятор.

Цитата:
с эвалом даже получше дела обстоят:
У тебя разные вещи происходят в eval и Function, или ты не заметил?

ЗЫ: а вообще ты мне надоел, можешь гавнокодить как тебе захочется.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.07.2014 в 14:07.
Ответить с цитированием
  #8 (permalink)  
Старый 06.07.2014, 14:07
foo foo вне форума
Профессор
Отправить личное сообщение для foo Посмотреть профиль Найти все сообщения от foo
 
Регистрация: 17.05.2014
Сообщений: 197

Сообщение от kobezzza
У тебя разные вещи происходят в eval и Function, или ты не заметил?
Это не столь важно
a=eval("(function(){'test'})")
3: 1267ms

Последний раз редактировалось foo, 06.07.2014 в 14:24.
Ответить с цитированием
  #9 (permalink)  
Старый 06.07.2014, 14:08
foo foo вне форума
Профессор
Отправить личное сообщение для foo Посмотреть профиль Найти все сообщения от foo
 
Регистрация: 17.05.2014
Сообщений: 197

Сообщение от kobezzza
можешь гавнокодить как тебе захочется.
Дело не в этом. Важно докопаться до истины.
Ответить с цитированием
  #10 (permalink)  
Старый 06.07.2014, 14:14
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Т.е. ты не видешь, что

Function("test")


и

function(){"test"}


Это разные по функционалу функции?

alert(Function("test").toString())


Более того, на таких убогий тестах вообще нельзя делать никаких выводов.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.07.2014 в 14:17.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вызов функции Hol1killer Prototype & script.aculo.us 11 05.12.2016 01:37
В ИЕ 10 не работает скрипт alexmixaylov Internet Explorer 2 15.09.2013 15:41
не работает ajax в IE xber9 jQuery 5 27.08.2013 21:04
Jin: И снова о наследовании tenshi Ваши сайты и скрипты 16 19.08.2013 20:30
Подскажите,как решить 2 вопроса dima*** Общие вопросы Javascript 28 06.05.2013 22:35