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

Javascript/jQuery "Gotchas"

Каковы некоторые из распространенных Javascript и/или jQuery "gotchas", которые вы видели или были сработаны?

В качестве примера мне сегодня утром было указано, что при выполнении parseInt() вы должны быть осторожны с radix, потому что, если ваша строка начинается с 0, по умолчанию будет равен 8.

4b9b3361

Ответ 1

Замена .round()/.floor() или .ceil() на ~~ для вырезания десятичных знаков довольно красива.

Вместо

Math.floor(Math.random() * 100);

вы делаете

~~(Math.random() * 100);

Он просто короче и имеет лучшую производительность даже!

Ответ 2

Объем 'this'

Рассмотрим следующий пример:

function myClass(message) {
  this.message = message;
  $('button').click(function(){
    this.onClick();
  });      
}

myClass.prototype.onClick = function() {
  alert(this.message);
}

Конечно, строка 3 не работает: this работает на основе каждой функции, а функция, определенная в строке 2, будет иметь выбранную кнопку как this вместо экземпляра myClass. Там даже более проницательная версия:

function myClass(message) {
  this.message = message;
  $('button').click(this.onClick);    
}

myClass.prototype.onClick = function() {
  alert(this.message);
}

Это вызывает правильную функцию, но this все равно будет кнопкой (потому что this определяется вызывающим абонентом, а не тем фактом, что вы являетесь функцией-членом). Правильное решение заключается в использовании промежуточной переменной, например self, для применения правил правильной привязки к this:

function myClass(message) {
  this.message = message;
  var self = this;
  $('button').click(function() { self.onClick(); });    
}

Тип литья

[] == ![] оценивает значение true по неясным причинам

Массивы и свойства

Свойство length работает только для целых ключей на массивах. Например:

var a = [];        // a.length == 0
a[0]   = 'first';  // a.length == 1
a['1'] = 'second'; // a.length == 2
a['x'] = 'third';  // a.length == 2 <-- 'x' does not count

В этом разделе for( in ) работает с массивами, но обходит свойства all, определенные в массиве. Это означает, что ваш JavaScript-код, который использует for( in ) для итерации через массивы, внезапно перестанет работать с определенными браузерами при добавлении ExtJS в ваш проект, поскольку ExtJS определяет Array.prototype.filter, если он не присутствует (это известно как исправление обезьяны). Поскольку теперь filter является настраиваемым свойством каждого объекта массива, все ваши циклы также проходят через него. Boom.

Чистый способ итерации через массив использует длину и инкремент для цикла. Или jQuery $.each().

Ответ 3

Самая большая WTF, с которой я столкнулся в Javascript, должна быть String.replace.

Возьмите этот код, например:

"An,example,of,a,comma,separated,sentence".replace(',', ' ');

Это создает предложение, красиво разделенное пробелами вместо этого, правильно?

К моему полному удивлению: нет, нет. Он заменяет только первую запятую пробелом, оставляя остальных нетронутыми. Если вы хотите выполнить фактическую замену, вы должны использовать .replace(/,/g, ' ').

Почему метод не называется "replaceFirst", все догадываются.

Ответ 4

я бы рекомендовал читать целые http://wtfjs.com/

Ответ 5

Оператор return должен иметь сразу после него значение или, по крайней мере, начинать с той же строки:

return 4;   // returns 4
return {};  // returns an empty object
return {    // returns an empty object
};          
return      // returns undefined
{
};

Ответ 6

Ajax получает/сообщения в статическом URI, может кэшироваться IE. Поэтому вам нужно добавить постоянно меняющийся параметр, быстрый и простой способ - добавить new Date().getTime()

Ответ 7

Книга Дугласа Крокфорда JavaScript: Хорошие части - отличное чтение по этой теме. В нем есть и плохие и ужасные части Javascript:)

Ответ 8

Очень хорошая статья недавно была опубликована в блоге Elijah Manor, Enterprise jQuery. Он написан на Javascript "gotchas" для разработчиков С#. Это серия частей, и есть ряд хороших моментов, которые также будут "получать" людей, знакомых с другими языками.

Посмотрите здесь: Как хорошие привычки на С# могут поощрять плохие привычки JavaScript.

Ответ 9

Переменные области и переменные цикла, безусловно, являются "полученными". Это происходит при назначении обработчиков событий в цикле:

var lis= document.getElementsByTagName('li'),
    imgs = document.getElementsByTagName('img');
for (i = 0; i < elements.length; i++)
{
    elements[i].onclick = function() {
        imgs[i].src = elements[i].innerHTML;
    }
}

Во время выполнения imgs[i] будет undefined, вызывая ошибку при попытке доступа к imgs[i].src. То же самое для elements[i] и его innerHTML.

Ответ 10

Подразумеваемые глобальные значения являются большими:

var x = 12, y = 14;
function addOne(num)
{
    x = num + 1;    // since this is not declared with 'var', it is implied global
    return x;
}

alert(addOne(y));    // alerts '15'
alert(addOne(x));      // alerts '16'

Это простой и нереалистичный пример, но хорошо демонстрирует проблему.

Ответ 11

Javascript

parseInt('0aaa') //still returns 0
parseFloat('0.aaa') //still returns 0

Это больше фактор oops. При написании инструкции switch я, как известно, забыл поместить перерыв в инструкции, что вызывает проблемы.

var myvar = '1'
switch (myvar) {
  case '1':
     alert(myvar);
  case '2':
     alert(myvar);
     break;
}

Поскольку я забыл прорыв в case '1', вы получите предупреждение дважды.