Каковы верхние ошибки JavaScript?

Я планирую дать вступительный разговор на JavaScript и в процессе подготовки, я задавался вопросом, каковы верхние ловушки, в которые входят новички.

Я знаю, что у меня было несколько gotchas, прежде чем я полностью понял закрытие, но большая часть странного поведения в JavaScript не то, о чем я думаю больше...

Итак, какие подводные камни вы должны указать на новичков?

Ответ 1

Преобразование типа Boolean.

''        ==   '0'           //false
0         ==   ''            //true
0         ==   '0'           //true
false     ==   'false'       //false
false     ==   '0'           //true
false     ==   undefined     //false
false     ==   null          //false
null      ==   undefined     //true
" \t\r\n" ==   0             //true

Также как разница между null и undefined. Как указано в таблице выше, сравнение null и undefined с == возвращает true, но с === возвращает false. Такое поведение имеет смысл, если вы понимаете, что undefined сильно отличается от переменной, имеющей значение null, а значение, содержащее значение undefined, отличается от значения undefined.

Ответ 2

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

var foo = { 
    bar: "bar", 
    baz: "baz", 
};

Примечание @JulianR комментарий: В массивах IE не подводит себя напрямую, бросая некоторую синтаксическую ошибку, но сбой при попытке использовать массив, потому что добавленная запятая заставляет IE думать о наличии еще одного элемента в массиве со значением undefined, чем на самом деле, Поэтому, если у вас когда-либо была ошибка, потому что по какой-то причине последний элемент в массиве undefined: это запятая.

Ответ 3

По общему признанию, я был виновен в некоторых из них в прошлом, потому что ваше развлечение было тем, что выделено жирным шрифтом:

  • Не знаю неправильных (и очень немногих правильных) использования eval
    eval("obj."+prop);
  • Использование операторов with
  • Использование parseInt(str, base) без указания аргумента base.
  • Использование this в функциях таймера/обратного вызова.
  • Использование eval-подобных выражений в таймерах
    setTimeout("someFunc(myScopedVarWhoops)");
  • Мышление jQuery - это имя языка, который вы кодируете
  • Выполнение простых задач JavaScript с использованием фреймворка - $(1).plus(1) кто-нибудь?;-)
  • Использование continue без увеличения или изменения условной переменной.
  • Наводнение глобального пространства имен с помощью переменных
  • Забыть var в операторах или перед for. for (i=0;i<10;i++)
  • Использование obfuscator и просто позволить ему работать на вашем коде
  • Не совсем ловушка, но бессмысленная - return condition ? true : false; вместо return condition;
  • Не комментируя свой код, применяется ко всем языкам.
  • Использование операторов try...catch...finally для улавливания ошибок вместо использования операторов if для проверки переменных.
  • Глупо пытаться остановить "источник просмотра", блокируя щелчки правой кнопкой мыши на ваших страницах (я был молодым * sobs *!)
  • Используя { 0: "Foo", 1:"Bar", 2:"Foobar" } вместо [ "Foo", "Bar", "Foobar" ]
  • Использование parseInt() для ввода пользователем
    parseInt("1,000") // -> 1, wrong!
    +"1,000" // -> NaN, correct!

Некоторые уже упомянули:

  • Невозможно использовать операторы строгого равенства (===)
  • Установка обработчиков событий на возвращаемое значение функции вместо ссылки на указанную функцию
  • Не ; завершение утверждений правильно
  • Использование for...in циклов на массивах

Можно подумать еще об этом после того, как я спал: -)

Ответ 4

  • Забыв объявить переменные с помощью var
  • Непонимание (или не понимание) области видимости и закрытия переменных
  • Попытка решить неприятные проблемы совместимости, которые уже создали команды фреймов.

Ответ 5

+ для конкатенации строк:

var a = '2';
var b = 3;

a * b #  6
a - b # -1
a + b #  23

Ответ 6

Строки JavaScript не являются байтовыми строками и не являются даже строками Unicode. Это строки UTF-16.

Пример:

> "♫".length
1
> "𐌈".length
2
> "𐌈".charAt(0)
"\uD800"
> "𐌈".charAt(1)
"\uDF08"
> "𐌈" === "\uD800\uDF08"
true

Если это выглядит как мусор, обвините своего браузера в том, что он имеет неправильную обработку Unicode (или, возможно, ваш шрифт, поскольку у него нет символа "OLD ITALIC LETTER THE" ).

Ответ 7

Самые большие трудности, которые я вижу для новичка, понимают контекст выполнения (то есть, что "this" означает, когда и где он встречается) и прототип системы наследования.

Ответ 8

  • Closures - иначе известные как лямбда-функции - следите за утечками памяти.
  • Различия в браузере, тестирование как в Internet Explorer, так и по крайней мере в одном другом браузере является обязательным. Функции, которые работают только в некоторых браузерах или работают по-разному в разных браузерах, как правило, следует избегать. Если это невозможно, конкретному ветвлению в браузере лучше всего выполнять обнаружение функций браузера вместо версий браузера. Это увеличивает вероятность того, что код будет работать в будущих браузерах и браузерах, которые не были протестированы.
  • Взять слишком сильно в jQuery или Ajax, и не зная, что подчеркивание JavaScript достаточно хорошо, чтобы знать, как исправить проблемы с картой.
  • Не зная, что JavaScript может в какой-то мере использоваться для написания кода ООП. На самом деле это может дать вам очень базовую структуру ООП с объектами.
  • Чувствительность к регистру (если вы разработчик VB.NET)
  • Защита IP - зная, что вы можете запутать JavaScript, но исходный код, который вы там поместили, будет очень легко украсть и реконструировать. Это может быть даже не проблема в зависимости от сложности клиентского приложения, которое вы пишете.

Я больше не могу думать, но надеюсь, что это поможет.

Ответ 9

  • Использование window.onload = init(); вместо window.onload = init;
  • Булевы эквивалентности (как уже упоминалось)
  • Замыкания внутри цикла.
  • Использование варианта цикла for in для итерации по массивам.
  • Не использовать ;, потому что он "необязательный".
  • this (просто... в общем:))
  • Не использовать var
  • Зная, что obj.ref === obj["ref"]

Ответ 10

  • Создание сайтов, которые не работают без JavaScript
  • Использование JavaScript для вещей, которые должны выполняться на стороне сервера
  • Использование фреймворков для простых задач, которые их не требуют.

Ответ 11

Не настоящая кодовая ошибка, но более общая мысль:
Не доверяйте тем, что делает ваш JavaScript, возможно, он был отключен или даже обезьяна исправлена ​​. Это означает, что никогда не полагайтесь на проверку на стороне клиента. НИКОГДА.

Ответ 12

Вся концепция прототипирования занимает некоторое время, чтобы полностью понять, но вот некоторые общие ошибки:

Забыв reset свойство конструктора после назначения объекта-прототипа:

var Foo() = function ()
{
    this.batz = '...';
};
Foo.prototype = new Bar();
Foo.prototype.constructor = Foo;

Если вы забудете наименьшую строку, new Foo() выполнит Bar().

Другая ошибка с прототипированием - итерация по объектам/массивам без фильтрации элементов прототипа:

for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        //stuff...
    }
}

Дополнительное условие пропустит любые элементы, которые унаследованы от прототипа obj.

Ответ 13

typeof null is object


>>> var i = 1 + undefined; i;
NaN
>>> var i = 1 + null; i;
1