В чем разница между void, eval и конструктором Function в JavaScript?
void(document.body.innerText += 'hi')
eval(document.body.innerText +='\nbye')
Function(document.body.innerText += '\n!!!')
void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())();
eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())();
Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())();
Какова модель обработки для выполнения кода в этих различных операторах?
void(alert('hi'))
undefined
eval(alert('hi'))
undefined
Function(alert('hi'))
function anonymous() {
undefined
}
eval(Function(function foo(){return true}).toString())();
TypeError: undefined is not a function
void(Function(function foo(){return true}).toString())();
TypeError: string is not a function
Function(Function(function foo(){return true}).toString())();
undefined
3 ответа
В этой статье eval
а также Function
Конструкторы объясняются:
(…) Глобальный, встроенный
eval
Функция оценивает код в области вызова.Код, выполняемый из функции, созданной
Function
Конструктор на самом деле не выполняется в глобальном масштабе. Однако он также не выполняется в локальной области, что, вероятно, приводит к путанице.Function
Конструктор создает функцию, цепочка областей действия которой состоит из ничего, кроме глобальной области (конечно, с предшествующим собственным объектом активации функции). Любой код, содержащийся в функции, созданной с помощьюFunction
Конструктор оценивает в области действия этой функции, а не в глобальной области. Тем не менее, это почти как если бы код выполнялся глобально, так как глобальный объект - следующий объект в цепочке областей действия.
И согласно этой странице, void
просто возвращается undefined
:
На многих языках
void
это тип, который не имеет значений. В JavaScriptvoid
это оператор, который принимает операнд и возвращаетundefined
, Это не полезно, и это очень запутанно. избежатьvoid
,
Вот краткое изложение различий оценки:
void
оценивает код в области действия содержащей функцииeval
оценивает строки в области действия содержащей функцииFunction
оценивает код в своей области видимости
и обратная разница:
void
всегда возвращает неопределенноеeval
возвращает возвращаемое значение выполненного кодаFunction
возвращает анонимную функцию
Рекомендации
- JS101: конструктор функций
- Объяснение ошибки JSLint: конструктор функции является eval
- Как зло является Eval
- [[Scope]] функций, созданных с помощью конструктора функций
- Оценка кода JavaScript с помощью eval() и новой функции ()
- Gmail для мобильных устройств серии HTML5: сокращение задержки запуска - официальный блог Google Code
- Быстрая загрузка через Eval() - SproutCore
- (вниз) Загрузка JavaScript в виде строк | Высокопроизводительные веб-сайты
- Выражения против высказываний в JavaScript - доктор Аксель Раушмайер
- Оператор void в JavaScript
Стоит отметить, что вы полностью злоупотребляете этими функциями.
void
просто оценивает какое-то выражение и возвращает неопределенное.Обратите внимание, что это оператор, а не функция, поэтому не нужно заключать оперант в круглые скобки.
Это полезно только для получения значения undefined, если вы беспокоитесь
undefined
может быть затенен, или если вы хотите ввести меньше символов.Вместо
var undef = void(document.body.innerText += 'hi')
лучше использовать
document.body.innerText += 'hi'; var undef = void 0;
И если вам не нужно быть неопределенным, не используйте
void
совсем.eval
должен вызываться со строкой. Эта строка оценивается как код. Точное поведение зависит от того, вызываете ли вы его в строгом или небрежном режиме, и является ли это прямым или косвенным вызовом.Если вы не вызовете его со строкой, он просто вернет аргумент.
В твоем случае,
eval(document.body.innerText += '\nbye')
будут:- Бежать
document.body.innerText += '\nbye'
возвращает новое значение, например"hello\nbye"
, - Оцените полученный текст как код. Скорее всего, это бросит.
Я почти уверен
eval(document.body.innerText +='\nbye')
это не то, что вы хотите, но вот (не рекомендуется) контрпример:var myvar = 0; var bye = 123 eval(document.body.innerText += '\nbye'); console.log(myvar); // 123
myvar =
- Бежать
Function
конструктор в основном какeval
, но он создает функцию вместо того, чтобы сразу же выполнять оценку строки как кода.document.body.innerText += '\n!!!'
не может вернуть допустимую строку, поэтому она просто выбросит.Тогда у вас есть несколько странных сочетаний этих функций.
Если вы передаете функцию
Function
конструктор, он будет строковым.Function
Конструктор вернет анонимную функцию, которая просто объявит функцию как аргумент. Это бессмысленно.Если вы позвоните
toString
, это приведет к строчкам анонимной функции.Затем,
void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())();
будет пытаться вызвать эту строку. Но строки не могут быть вызваны. Ошибка.А также
eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())();
оценит расслоение. Просто почему? Но объявления функций не возвращают значение, поэтому вы просто получите undefined, который не вызывается. Ошибка.А также
Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())();
будет зачеркнутfoo
, проанализируйте его для анонимной функции, зафиксируйте анонимную функцию и снова проанализируйте ее для другой анонимной функции. Пожалуйста, не делай этого. Наконец, вызов вернет undefined, потому что там нет оператора return.