Pull to refresh

Comments 34

по 13 — для старых то да, а для новых то нет.
по 14 — а тот не вернет новый массив разве?
А в том, что Товарищ Муслики делает вроде как не — или я ошибаюсь?
Да, там массив изменяется 'на месте'. Но, на мой взгляд, concat вещь более очевидная, чем push.apply
Так то да — я сам в 9 из 10 сделаю `concat`, а про то, что вот `push.apply`…
13 — есть полифилы
Добавлю ещё один совет — как создать массив заданной длины, заполненный undefined:

Array.apply (null, new Array (N))

Стандартная операция «new Array (N)» вернёт пустой массив, так что тот же map с ним не сработает.
О! Есть ещё такой трюк в JS: при помощи плюса можно сложить два числа:
alert(2 + 2) // 4


Это я к чему. Отчасти статья капитанство, отчасти вредные советы, отчасти неправильно объяснённые конструкции.

2 — Используйте `===` вместо `==` :

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

5 — Объект через конструктор :

Ну, бляха, это вообще можно про любую встроенную конструкцию так написать. Просто цитата из документации:
Вывод текста в консоль: console.log(123);
Создание функции: function () {}
Зачем в «трюки» записывать элементарные вещи?

6 — Будьте осторожны, когда используете `typeof, instanceOf, constructor`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var arr = ["a", "b", "c"];
        typeof arr;   // return "object"
        arr  instanceof Array // true
        arr.constructor();  //[]

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

А что, разве ожидается другое от typeof и вызова constructor?

7 — Используйте self-calling функции :

Написано использовать, не написано зачем.

8 — Получение произвольного значения массива :

о! Давайте в трюки будем вставлять библиотечные функции. В MooTools их десятки
И назовём это «трюками». Например, «трюк на JS», узнаём, содержит ли массив элемент:

function contains (array, elem) {
  return array.indexOf(elem) >= 0;
}


Аналогичная ересь в 9-19

23 – Используйте `map()`метод, чтобы пройти циклом по массиву :

Ухты, я прочитал документацию по языку и оказывается, у Array есть метод map! Надо срочно написать об этом статью!

24 – Округление числа до N чисел после запятой :

А у String есть метод toFixed! Это вообще круть!

Надо будет дать ему ссылки на методы Array.filter и String.indexOf

31 – Сериализация и десериализация (для JSON) :

К предыдущим двум пунктам.

28 – Кешируйте переменные, которые необходимы для вычислений или запросов:
На примере jQuery селекторов, мы можем закешировать их результат — DOM элементы.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var navright = document.querySelector('#right');
        var navleft = document.querySelector('#left');
        var navup = document.querySelector('#up');
        var navdown = document.querySelector('#down');

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Назвать CSS-селекторы JQuery-селекторами? Шикарно.

33 – Избегайте `with` (Хорошая штука):
Использование `with` определяет переменную в глобальное пространство. Если какая-либо переменная будет иметь такое же имя, тогда это создаст определенные проблемы, так как может произойти затирание значения.

Описание «with» — бред. Сейчас «with» deprecated, но совершенно по иной причине, чем описана в топике.

35 – Передавайте функции, а не строки для `setTimeout()` и `setInterval()` :

Наверное, единственный вменяемый совет в статье, но только совсем новички пишут так:
        setTimeOut('doSomethingAfterFiveSeconds()', 5000);


37 – Используйте `switch/case` выражение с численными диапазонами :

Вредный совет. Подобный «приём» сильно замедляет понимание кода сторонними разработчиками.

38 – Создать объект, чей прототип — это задаваемый объект:
Возможно создать функцию, что создает объект, чьим прототипом будет является объект, который передается в аргументе функции…

Спасибо, капитан. Только зачем?

39 – HTML escaper :

Ещё одна библиотечная функция?

40 – Избегайте использования `try-catch-finally` внутри циклов:
`try-catch-finally` создает новую переменную в текущем пространстве выполнения каждый раз, когда срабатывает исключение и оно связывается с переменной.

Создаёт новую переменную? Что за бред?

43 – Помните, что примитивы работают быстрее, чем вызовы функций.

array.push(foo) работает быстрее array[array.length] = foo, так что совет не в тему. И от того, что примитивы работают быстрее функций не значит, что все функции надо вручную разворачивать и писать каждый раз заново.

Так что, статья — шлак.
39. Нет лучшего HTML-escaper'а в браузере, чем сам браузер:
var d = document.createElement("div"); 
d.appendChild(document.createTextNode("this <b>is</b> html")); 
return d.innerHTML;
Создавать два дом-элемента просто чтобы эскейпнуть текст? Ну-ну)
UFO just landed and posted this here
UFO just landed and posted this here
Я вообще слабо представляю зачем в браузере эскейпить текст, но если это всё-таки нужно, то на большом количестве вызовов мои дом-элемены делают вложенную функцию с регуляркой в разы.
Единственно, конечно, дом нужно создавать только один раз:
var esc = {
    'reg': function (text) {
        var replacements= {"<": "<", ">": ">","&": "&", '"': """};
        return text.replace(/[<>&"]/g, function(character) {
            return replacements[character];
        });    
    },
    
    'dom': function (text) {
        var s = document.createElement("span"),
            t = document.createTextNode("");
            s.appendChild(t);
        function f(text) {
            t.nodeValue = text;
            return s.innerHTML;
        }
        esc.dom = f;
        return f(text);        
    }
};


Сравните скорость esc.reg и esc.dom

А уж если нужно от унескейпить текст, то посмотрю я на эту регулярку
UFO just landed and posted this here
34. Эта микрооптимизация хорошо даёт эффекты в цикле в цикле в цикле (математические вычисления, например). Век оптимизирующих компиляторов не может это ускорить в общем виде. Тут такое дело что не может оптимизатор знать чего хотел разработчик. То есть length может поменяться внутри цикла и тогда поведение будет разным с оптимизацией из совета и без. А поменяться оно может крайне хитрыми методами, например если мы напишем в цикле всего лишь c += arr[i] — нельзя гарантировать что length остался прежним по той причине что теперь в js были добавлены геттеры и сеттеры. Мы могли особо упороться и сделать геттер на третий элемент массива, который добавит или уберёт что-то, или просто поменяет length.
UFO just landed and posted this here
Хоть я и вижу отрицательное отношение сообщества к статье, но посмею сказать, что статья мне понравилась.

Да, много банальщины и экономии на спичках. Но читая весь этот длинный список трюков, волей-неволей вспоминаешь некоторые вещи, которые уже подзабыл. И в этом «плюс» этой статьи.
20 пункт ошибочен.
Массив в js ˜— это объект. У него изначально есть некоторые захардкоженные сеттеры. Если устанавливаемый key — число, то выполняется примерно this.length = max(key, this.length).
Delete действительно удалит:
var a = [1,2,3,4,5]; 
delete a[2]; 
for( var i in a ) 
    console.log(i);
// 0,1,3,4

Другое дело что в консолях браузера для удобства есть красивое отображение различных типов данных. Вот массив и отображается от 0 до length.
п. 20 не ошибочен. Автор говорит об удалении из массива, а не объекта. Конструкцию for (key in object) не используют для перебора массива.
Автор говорит что delete заменяет элемент массива на undefined, но он этого не делает. Он ведёт себя точно так же. Он не знает что вот эта хрень перед ним массив.
Не несите ересь.
Дырявые массивы — зло как с точки зрения компилятора и оптимизации кода, так и понимания, например, такой фимозный случай — см. «Оптимизация 3».
Банально, но for in по массиву — зло. Он медленнее обычного for. Полифилы es5, es6, разные библиотеки могут расширить прототип массива, в ie8- нельзя сделать свойства неперечислимыми — эти свойства попадут в for in.
demark, rock: я не говорю что надо использовать эту конструкцию для перебора массива. Эта конструкция даёт реальные свойства объекта и показывает что delete действительно удалил элемент. Какие полифилы, зачем полифилы, getOwnProperty же. Я только хотел показать что элемент фактически пропал. В js всё является объектами и массивы в том числе. Использование delete делает всё правильно, оно не знает о том что эта штука делает вид что она массив. То есть Delete не схлопнет удалённый элемент, не уменьшит length, но сам key->value убьёт. Дырявый массив является злом только из-за того что в этом случае получается worst case scenario поиска ключа по хешу, но не более того.
Ошибочна только формулировка «не удаляет, а заменяет элемент на undefined», на фоне остальных, в числе которых полный трэш, совет один из самых адекватных. Вы же утверждаете, что «пункт ошибочен». «Использование delete делает всё правильно», но совсем не то, что нужно программисту. Видел трэш, где из массива удаляли элементы с помощью delete, добавляли с помощью push, перебирали с помощью .forEach и удивлялись, почему со временем код работает всё медленней.
Да, формулировка «в js всё является объектами» не менее ошибочна.
UFO just landed and posted this here
34. Длина массива в коде ниже не вычисляется каждый раз. Каждый раз происходит бинарный поиск «length» в хэше ключей объекта «arrayNumbers». Такой поиск имеет ln2 сложность. То есть если в массиве 1023 элемента и мы ищем свойство length, то в худшем случае в глубинах v8 будет выполнено 10 условных операций сравнения.
for(var i = 0; i < arrayNumbers.length; i++) {
    sum += arrayNumbers[i];
}


36. Очень часто вместо switch в таком случае лучше использовать заранее подготовленный хэш объект. Опять же сложность становится ln2, что значит что 511 else выродятся всего в 9 реальных операций сравнения в худшем случае. Это работает только если в ветвлениях условие проверки равенства и стоит учесть что в таком случае попутно будет происходить приведение значения к строке.

38. Object.create( object ) сделает то же самое нативно. Хотя выше это уже написали
Object.create появился только в ES5. Знать как написать naive polyfill вполне полезно.
Number.toFixed возарвщает String, так что если вы хотите округлить, а не отформатировать, то правильнее пользоваться +num.toFixed(4)
— Надо быть очень аккуратным с перемешиванием массива используя numbers.sort(function(){ return Math.random() - 0.5});. Если он относительно большой то перемешан он будет более чем неравномерно. Примитивная мешалка массива из 10 элементов — идеально :)
Sign up to leave a comment.

Articles