Подтвердить что ты не робот

Насколько опасно это в JavaScript, действительно, предположить, что undefined не перезаписывается?

Каждый раз, когда кто-либо упоминает тестирование с undefined, он указал, что undefined не является ключевым словом, поэтому it может быть установлено на "hello", поэтому следует использовать typeof x == "undefined". Это кажется мне смешным. Никто никогда не сделает этого, и если бы они это сделали, было бы разумно никогда не использовать какой-либо код, который они написали... правильно?

Я нашел один пример того, кто случайно установил undefined в null, и это было дано как причина, чтобы не предполагать, что undefined isn ' t перезаписано. Но если бы они это сделали, ошибка исчезла бы, и я не понимаю, как это лучше.

В С++ все хорошо знают, что законно говорить #define true false, но никто никогда не советует вам избегать true и использовать 0 == 0. Вы просто предполагаете, что никто никогда не будет достаточно большим рывком, чтобы сделать это, и если они это сделают, никогда больше не верьте их коду.

Неужели это когда-либо на самом деле укусил кого-то, кого кто-то назначил на undefined (специально), и он сломал ваш код, или это скорее гипотетическая угроза? Я готов принять мои шансы сделать мой код немного более удобочитаемым. Это действительно плохая идея?

Повторяю, я не прошу, как защитить от переназначенного undefined. Я видел эти трюки, написанные уже 100 раз. Я спрашиваю, как опасно не использовать эти трюки.

4b9b3361

Ответ 1

Нет, никогда не было. В основном это связано с тем, что я разрабатываю современные браузеры, которые в основном совместимы с ECMAScript 5. В стандарте ES5 указано, что undefined теперь только для чтения. Если вы используете строгий режим (вы должны), ошибка будет выброшена, если вы случайно попытаетесь ее изменить.

undefined = 5;
alert(undefined); // still undefined
'use strict';
undefined = 5; // throws TypeError

Что вам не следует делать, это создать свой собственный scoped, изменяемый undefined:

(function (undefined) {
    // don't do this, because now `undefined` can be changed
    undefined = 5;
})();

Константа в порядке. Все еще ненужно, но прекрасно.

(function () {
    const undefined = void 0;
})();

Ответ 2

Ни один правильный код не сделает такого. Но вы никогда не узнаете, что сделал какой-то wannabe-smart developer или плагин /library/ script, который вы используете. С другой стороны, это крайне маловероятно, и современные браузеры не позволят перезаписывать undefined вообще, поэтому, если вы используете такой браузер для разработки, вы быстро заметите, пытается ли какой-либо код перезаписать его.


И даже если вы не просили об этом - многие люди, вероятно, найдут этот вопрос при поиске более распространенной проблемы "как защитить от переопределенного undefined", поэтому я все равно отвечу:

Там очень хороший способ получить действительно undefined undefined независимо от того, сколько лет браузер:

(function(undefined) {
    // your code where undefined is undefined
})();

Это работает, потому что аргумент, который не указан, всегда undefined. Вы также можете сделать это с помощью функции, которая принимает некоторые реальные аргументы, например. например, когда вы используете jQuery. Обычно это хорошая идея, чтобы обеспечить нормальную среду таким образом:

(function($, window, undefined) {
    // your code where undefined is undefined
})(jQuery, this);

Тогда вы можете быть уверены, что внутри этой анонимной функции действуют следующие вещи:

  • $ === jQuery
  • window === [the global object]
  • undefined === [undefined].

Однако обратите внимание, что иногда требуется typeof x === 'undefined': если переменная x никогда не была установлена ​​в значение (вопреки настройке на undefined), чтение x по-другому, например if(x === undefined) выдаст ошибку. Однако это не относится к свойствам объекта, поэтому, если вы знаете, что y всегда является объектом, if(y.x === undefined) совершенно безопасен.

Ответ 3

Там есть простое решение: сравните с void 0, который всегда undefined.

Обратите внимание, что вам следует избегать ==, поскольку это может привести к принудительному увеличению значений. Вместо этого используйте ===!==).

Тем не менее, переменная undefined может быть установлена ​​по ошибке, если кто-то пишет = вместо == при сравнении чего-то против undefined.

Ответ 4

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

1) Создайте политическую команду, запретите переопределять undefined, зарезервировав ее для более популярного использования. Сканируйте существующий код для назначения undefined слева.

2) Если вы не контролируете все сценарии, если ваш код используется вне ситуаций, которые вы или ваши политики контролируете, то, очевидно, ваш ответ отличается. Сканируйте код, который использует ваши скрипты. Heck, сканируйте веб-страницу статистики undefined слева присваивания, если хотите, но я сомневаюсь, что это было сделано для вас, потому что проще просто вместо этого ответить # 1 или # 3.

3) И если этот ответ недостаточно хорош, возможно, потому, что вам нужен другой ответ. Возможно, вы пишете популярную библиотеку, которая будет использоваться внутри корпоративных брандмауэров, и у вас нет доступа к вызывающему коду. Затем используйте один из других прекрасных ответов здесь. Обратите внимание, что популярная библиотека jQuery обрабатывает звуковую инкапсуляцию и начинается:

(function( window, undefined ) {

Только вы можете ответить на свой вопрос таким образом, который вы ищете. Что еще можно сказать?

edit: p.s. если вы действительно хотите мое мнение, я скажу вам, что это не опасно. Все, что могло бы вызвать дефекты (например, присвоение undefined, которое, очевидно, хорошо документированное рискованное поведение), само по себе является дефектом. Это дефект, который является риском. Но это только в моих сценариях, где я могу позволить себе придерживаться этой перспективы. Как бы я вам рекомендовал, я ответил на вопрос о своих случаях использования.

Ответ 5

Безопасно протестировать против undefined. Как вы уже упоминаете. Если вы перейдете на какой-то код, который переопределяет его (что очень важно), просто не используйте его больше.

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

Ответ 6

Вы можете использовать undefined в своем коде при кодировании для браузеров, поддерживающих ECMAScript 5.1, так как неизменен в соответствии со спецификацией языка.

Также см. эту таблицу совместимости или this caniuse ECMAScript 5, чтобы увидеть, что все современные браузеры (IE 9+) внедрили неизменяемый undefined.

Ответ 7

Это совсем не опасно. Он может быть перезаписан только при запуске на ES3-движке и который вряд ли будет использоваться больше.

Ответ 8

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

Верно, что undefined не является ключевым словом. Но это примитив глобального уровня. Предполагалось, что это будет использоваться (см. "undefined" в developer.mozilla.org):

var x;
if (x === undefined) {
    // these statements execute
}
else {
    // these statements do not execute
}

Общей альтернативой этому (также из MDN), и, на мой взгляд, лучший способ:

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
    // these statements execute
}

if(x === undefined){ // throws a ReferenceError

}

Что имеет несколько преимуществ, очевидный (из комментариев) заключается в том, что он не вызывает исключение, когда x не объявлен. Стоит также отметить, что MDN также указывает, что в первом случае важно использовать === более ==, потому что:

var x=null;
if (x === undefined) {
    // this is probably what you meant to do
    // these lines will not execute in this case
}
else if (x == undefined) {
    // these statements will execute even though x *is* defined (as null)
}
else {
    // these statements do not execute
}

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

Заключение: Неправильно кодировать его первым способом и, конечно же, не опасно. Аргумент, который вы видели в качестве примера против него (его можно перезаписать), не является самым сильным аргументом для кодирования альтернативы с помощью typeof. Но использование typeof сильнее по одной причине: оно не генерирует исключения, когда ваш var не объявлен. Можно также утверждать, что использование == вместо === является распространенной ошибкой, и в этом случае она не делает то, что вы ожидали от нее. Так почему бы не использовать typeof?