У меня возникли проблемы с пониманием того, что в строгом режиме синтаксическая ошибка возникает, когда delete
используется для неквалифицированного идентификатора.
В большинстве случаев это имеет смысл... если вы объявляете переменные обычным способом с ключевым словом var
, а затем пытаетесь использовать delete
на них, в нестрочном режиме он будет терпеть неудачу, поэтому имеет смысл, если строгий режим терпит неудачу с ошибкой в этих случаях.
Однако есть случаи, когда вы не можете удалить идентификаторы, которые являются квалифицированными:
(function() {
// "use strict";
var obj = Object.create({}, { bloop: { configurable: false } });
delete obj.bloop; // throws TypeError in strict mode, silently fails in non-strict.
console.log('bloop' in obj); // true
}());
Строгий режим должен выполнять проверку времени выполнения, поскольку при столкновении возникает TypeError. Существуют также случаи, когда вы можете успешно удалить неквалифицированные идентификаторы в нестрогом режиме...
// "use strict";
window.bar = 6;
console.log(typeof bar); // number
delete bar; // works in non-strict, syntax error in strict!
console.log(typeof bar); // undefined
На самом деле, насколько я понимаю, можно ли удалять вещи (в нестрогом режиме), зависит от внутреннего свойства [[Configurable]]
и не имеет ничего общего с квалифицированными идентификаторами. Насколько я могу судить, в строгом режиме нет способа удалить неглобальные переменные, которые (как свойства локального VO) настраиваются:
(function() {
// "use strict";
eval('var foo = 5;');
console.log(typeof foo); // number
delete foo; // works in non-strict, SyntaxError in strict.
console.log(typeof foo); // undefined
}());
Итак, мой вопрос заключается в том, какой смысл бросать SyntaxError при использовании delete
на неквалифицированный идентификатор, когда TypeError будет бросать в любом случае, если свойство не настраивается? Это кажется ненужным ограничением, и в некоторых случаях, похоже, не существует какого-либо обходного пути, кроме использования строгого режима (третий пример). Может ли кто-нибудь объяснить мотивацию этого решения?
Обновление: я просто понял, что я упускаю из виду тот факт, что прямые вызовы eval
имеют свою собственную область действия в строгом режиме, а не в области вызывающей функции, поэтому в третьем примере foo
не будет определяться в строгом режиме, Во всяком случае, проверка времени выполнения все равно поймает это, но вызывает побочный вопрос: нет ли способа иметь настраиваемые локальные переменные в строгом режиме, как это происходит с объявлениями eval
'd variable в нестрочном? AFAIK, который был одним из немногих законных видов использования eval
.