45 Типсов-Триксов и Практик JavaScript

Одним вечером делать нечего, листая белые страницы интернета, в поисках чего бы такого мне почитать на сон грядущий, наткнулся я на одну занимательную статейку – на неизвестном мне ресурсе, от автора которого знать не знаю, слыхать не слыхал. Чтиво оказалось довольно интересным, с учетом того, что близко по роду деятельности, по форме и ее содержанию.

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

Естественно, что все ниже изложенное отнюдь не есть истина последней инстанции, как на библии, на ней клясться я бы не советовал. Но может быть кто-то откроет какие вещи с новой стороны, а кто – то покритикует, высказав свое ЧСВешное: «Фи фи фи, фа фа фа!».
Однако обо всем по порядку в моем своевольном от лица первого…

Кадр первый, вступительный


Как вы знаете, JavaScript номер один среди прочих языков программирования в мире: это язык для веба, язык для написания мобильных приложений ( прим. – опустил слово hybrid: mobile hybrid apps ) c PhoneGap и Appcelerator, для разработок на серверной стороне c NodeJS и Wakanda, и множества других применений. Это также отправная точка для многих новичков в мир программирования: может использоваться как для вывода простого alert в браузере, так и для управления роботом( с использованием  nodebot, nodruino).

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

В этой статье мне хотелось бы ознакомить с различными трюками и практиками, которые должны быть известны каждому JavaScript разработчику в независимости от внутренностей браузера ( browser/engine ), а также интерпретатора серверного кода javascript( Server Side JavaScript interpreter ).

Все примеры кода были протестированы в Google Chrome version 30, который
использует V8 JavaScript Engine (V8 3.20.17.15).


Кадр второй, поучительно-советовательный


1 — Не забывайте ключевое слово `var`, когда присваиваете значение переменной
первый раз :

Присвоение не объявленной ранее переменной приведет к тому, что данная переменная будет создана в глобальном пространстве. Избегайте этого.
(прим. — автор намекает, что когда вы создаете переменные, то можете
забыть ключевое слово, соответственно, создадите лишнюю переменную в
глобальном пространстве window)

2 — Используйте `===` вместо `==` :
Применение `==(!=)` производит преобразование типов, если это необходимо. Тогда как `===` не делает такого преобразования. Данный
оператор сравнивает не только значения, но также и типа, что разрешается быстрее, чем `==`. Примеры:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        [10] === 10    // is false
        [10]  == 10    // is true
        '10' == 10     // is true
        '10' === 10    // is false
         []   == 0     // is true
         [] ===  0     // is false
         '' == false   // is true but true == "a" is false
         '' ===   false // is false
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


3 — `undefined, null, 0, false, NaN, ''` :
Все вышеперечисленное всегда будет ложью в логических выражениях

4 — Не забывайте `;` :
Использование `;` для завершения выражений является хорошей практикой. Вы не будете предупреждены, если пропустите ее, так как JavaScript парсер вставит ее за вас.

5 — Объект через конструктор :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function Person(firstName, lastName){
            this.firstName =  firstName;
            this.lastName = lastName;
        }

        var Saad = new Person("Saad", "Mousliki");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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


7 — Используйте self-calling функции :
Часто их называют самовызывающимися анонимными функциями (Self-Invoked Anonymous Function) или немедленно вызываемым выражением функции (Immediately Invoked Function Expression (IIFE)). Это функция, которая запускается, непосредственно при создании и имеет следующую форму:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        (function(){
            // some private code that will be executed automatically
        })();
        (function(a,b){
            var result = a+b;
            return result;
        })(10,20);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(прим. — в данном пункте было трудно перевести, поэтому оставил оригинальные употребления на языке носителе, как их грамотно перевести
на русский ментальный, увы, не знаю. Думаю автор пытается намекнуть, что таким образом вы скроете свои реализации внутри анонимной функции, которую вызываете непосредственно в момент ее определения)

8 — Получение произвольного значения массива :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var items = [12,548,'a',2,5478,'foo',8852,'Doe',2145,119];
        var randomItem = items[Math.floor(Math.random() * items.length)];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


9 — Получение произвольного числа в определенном диапазоне :
Данный пример может использован, когда необходимо сгенерировать какие-либо фейковые данные, чтобы протестировать что-нибудь, к примеру, зарплаты, находящиеся между минимальными и максимальным значением:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var x = Math.floor(Math.random() * (max - min + 1)) + min;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


10 — Генерация численного массива от 0 до max :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var numbersArray = [] , max = 100;
        // numbers = [0,1,2,3 ... 100]
        for( var i=1; numbersArray.push(i++) < max;);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


11 — Генерация произвольного набора символов :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function generateRandomAlphaNum(len) {
            var rdmstring = "";
            for( ; rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
            return  rdmString.substr(0, len);
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


12 — Перемешивание массива :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
        numbers = numbers.sort(function(){ return Math.random() - 0.5});
        /* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


13 — Функция `trim()` для строк :
Классическая функция `trim()`, которая есть в Java, C#, PHP и многих других языках программирования, которая удаляет пробельные символы, не содержится в JavaScript. Однако можно добавить ее к объекту `String`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        String.prototype.trim = function(){
            return this.replace(/^\s+|\s+$/g, "");
        };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(прим. — не удержался, но странно, что автор использует данный прием,
как бы `trim()`есть уже в JavaScript)

14 - Добавить один массив к другому :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var array1 = [12 , "foo" , {name "Joe"} , -2458];

        var array2 = ["Doe" , 555 , 100];
        Array.prototype.push.apply(array1, array2);
        /* array1 will be equal to  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


15 — Преобразовать объект `arguments` в массив :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var argArray = Array.prototype.slice.call(arguments);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


16 – Проверка является ли заданный аргумент числом :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function isNumber(n){
            return !isNaN(parseFloat(n)) && isFinite(n);
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


17 – Проверка является ли заданный аргумент массивом :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function isArray(obj){
            return Object.prototype.toString.call(obj) === '[object Array]' ;
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Замечание, если метод `toString()` переопределен, то результат будет не такой какой ожидается при использовании данного трюка.
Или воспользоваться…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Array.isArray(obj); // its a new Array method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Вы также можете использовать `instanceof`, если не работаете с множеством фреймов. Однако, если вы используете много контекстов, то
получите неправильный результат:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var myFrame = document.createElement('iframe');
        document.body.appendChild(myFrame);

        var myArray = window.frames[window.frames.length-1].Array;
        var arr = new myArray(a,b,10); // [a,b,10]

        // instanceof will not work correctly, myArray loses his constructor
        // constructor is not shared between frames
        arr instanceof Array; // false
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


18 – Получить максимальное, минимальное значение численного массива :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
        var maxInNumbers = Math.max.apply(Math, numbers);
        var minInNumbers = Math.min.apply(Math, numbers);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


19 – Делаем массив пустым :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var myArray = [12 , 222 , 1000 ];
        myArray.length = 0; // myArray will be equal to [].
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


20 – Не используйте `delete` для того, чтобы удалить из массива :
Используйте `split` вместо `delete`, чтобы удалить запись из массива. Использование `delete` не удаляет, а заменяет элемент на `undefined`.
Вместо этого…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
        items.length; // return 11
        delete items[3]; // return true
        items.length; // return 11
        /* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Используйте вот это…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
        items.length; // return 11
        items.splice(3,1) ;
        items.length; // return 10
        /* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Однако `delete` следует использовать для удаления свойств объекта.

21 – Урезаем массив, используя `length` :
Как в предыдущем примере с пустым массивом, для урезания массива воспользуемся свойством `length`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];
        myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Бонус, если установить значение длины массив больше его текущей, то длина массива будет изменена, а новые значения будут установлены
как `undefined`. Свойство длины массива не только для того, чтобы его считывать.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        myArray.length = 10; // the new array length is 10
        myArray[myArray.length - 1] ; // undefined
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


22 – Использование логических `AND/ OR` для условных выражений :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var foo = 10;
        foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
        foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Логическое `OR` может быть также использовано, чтобы установить значение по умолчанию для аргумента функции.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Function doSomething(arg1){
            Arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


23 – Используйте `map()`метод, чтобы пройти циклом по массиву :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var squares = [1,2,3,4].map(function (val) {
            return val * val;
        });
        // squares will be equal to [1, 4, 9, 16]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


24 – Округление числа до N чисел после запятой :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var num =2.443242342;
        num = num.toFixed(4);  // num will be equal to 2.4432
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


25 – Проблема плавающих точек :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        0.1 + 0.2 === 0.3 // is false
        9007199254740992 + 1 // is equal to 9007199254740992
        9007199254740992 + 2 // is equal to 9007199254740994
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Почему так происходит? 0.1 + 0.2 равняется 0.30000000000000004. Что вам необходимо знать так это то, что все числа в JavaScript с плавающей точкой внутри представляются как 64 битные в двоичном виде по стандарту IEEE 754.
Если хотите больше примеров - посмотрите данный блог.
Вы можете использовать методы `toFixed()` и `toPrecision()`, чтобы избежать подобных проблем.

26 – Проверяйте свойства объекта, когда пользуетесь `for-in` циклом :
Данный пример кода может быть использован, чтобы избежать итераций по свойствам прототипа объекта.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        for (var name in object) {
            if (object.hasOwnProperty(name)) {
                // do something with name
            }
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


27 – Оператор запятая :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var a = 0;
        var b = ( a++, 99 );
        console.log(a);  // a will be equal to 1
        console.log(b);  // b is equal to 99
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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


29 – Проверьте аргумент прежде, чем отправить его в isFinite()` :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        isFinite(0/0) ; // false
        isFinite("foo"); // false
        isFinite("10"); // true
        isFinite(10);   // true
        isFinite(undifined);  // false
        isFinite();   // false
        isFinite(null);  // true  !!!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


30 – Избегайте отрицательных индексов в массивах :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var numbersArray = [1,2,3,4,5];
        var from = numbersArray.indexOf("foo") ;  // from is equal to -1
        numbersArray.splice(from,2);    // will return [5]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Убедитесь, что аргументы передаваемые `indexOf` не отрицательны.

31 – Сериализация и десериализация (для JSON) :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
        var stringFromPerson = JSON.stringify(person);
        /* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */
        var personFromString = JSON.parse(stringFromPerson);
        /* personFromString is equal to person object  */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


32 – Избегайте `eval()` или `Function` конструктора :
Использование `eval` или `Function` конструктора дорогостоящая операция так как каждый раз они вызывают преобразование исходного кода в исполняемый движком javascript.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var func1 = new Function(functionCode);
        var func2 = eval(functionCode);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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

34 – Избегайте `for-in` циклов для массивов :
Вместо…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var sum = 0;
        for (var i in arrayNumbers) {
            sum += arrayNumbers[i];
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

…лучше это…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var sum = 0;
        for (var i = 0, len = arrayNumbers.length; i < len; i++) {
            sum += arrayNumbers[i];
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Бонус, присвоение для `i` и `len` будет произведено лишь однажды так как это первое выражение конструкции цикла. Это быстрее, чем …
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        for (var i = 0; i < arrayNumbers.length; i++)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Почему? Длина массива `arrayNumbers` вычисляется при каждой итерации цикла.

35 – Передавайте функции, а не строки для `setTimeout()` и `setInterval()` :
Если вы передаете строки в `setTimeout()` или `setInterval()`, то они будут обрабатываться также как и с использованием `eval`, это медленно.

Вместо использования…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        setInterval('doSomethingPeriodically()', 1000);
        setTimeOut('doSomethingAfterFiveSeconds()', 5000);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

…используйте…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        setInterval(doSomethingPeriodically, 1000);
        setTimeOut(doSomethingAfterFiveSeconds, 5000);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


36 – Используйте `switch/case` вместо серии из `if/else` :
Использование `switch/case` работает быстро, когда более двух условий, это более элегантно и лучше для организации кода. Избейгате этого
выражения, когда имеется более 10 условных выражений.

37 – Используйте `switch/case` выражение с численными диапазонами :
Использование `switch/case` выражения с численным диапазоном делает возможным следующий трюк.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function getCategory(age) {
            var category = "";
            switch (true) {
                case isNaN(age):
                    category = "not an age";
                    break;
                case (age >= 50):
                    category = "Old";
                    break;
                case (age <= 20):
                    category = "Baby";
                    break;
                default:
                    category = "Young";
                    break;
            };
            return category;
        }
        getCategory(5);  // will return "Baby"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


38 – Создать объект, чей прототип — это задаваемый объект :
Возможно создать функцию, что создает объект, чьим прототипом будет является объект, который передается в аргументе функции…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function clone(object) {
            function OneShotConstructor(){};
            OneShotConstructor.prototype= object;
            return new OneShotConstructor();
        }
        clone(Array).prototype ;  // []
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


39 – HTML escaper :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        function escapeHTML(text) {
            var replacements= {"<": "<", ">": ">","&": "&", "\"": """};
            return text.replace(/[<>&"]/g, function(character) {
                return replacements[character];
            });
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


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

Вместо этого…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var object = ['foo', 'bar'], i;
        for (i = 0, len = object.length; i <len; i++) {
            try {
                // do something that throws an exception
            }
            catch (e) {
                // handle exception
            }
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

…используйте это…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var object = ['foo', 'bar'], i;
        try {
            for (i = 0, len = object.length; i <len; i++) {
                // do something that throws an exception
            }
        }
        catch (e) {
            // handle exception
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


41 – Устанавливайте задержки для `XMLHttpRequests` :
Вы можете потерять соединение, если XHR занимает слишком большое время (как пример, сетевые проблемы), используйте `setTimeout()` с вызовами
XHR.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var xhr = new XMLHttpRequest ();
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                clearTimeout(timeout);
                // do something with response data
            }
        }
        var timeout = setTimeout( function () {
            xhr.abort(); // call error callback
        }, 60*1000 /* timeout after a minute */ );
        xhr.open('GET', url, true);

        xhr.send();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Как бонус, вам следует избегать синхронных запросов Ajax.

42 – Deal with WebSocket timeout
Обычно, когда соединение установлено, сервер может сбросить соединение по тайм-ауту после 30 секунд неактивности. Фаервол может также после определенного периода сбросить соединение по тайм-ауту из-за неактивности.
Данную проблему можно решить путем посылок пустых сообщений серверу. Чтоб сделать это, следует добавить две функции в ваш код: одна, чтобы поддерживать соединение и другая, чтобы отменить эту поддержку.
Используя данный трюк, вы будете управлять тайм-аутом.

Добавляем `timerID`…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var timerID = 0;
        function keepAlive() {
            var timeout = 15000;
            if (webSocket.readyState == webSocket.OPEN) {
                webSocket.send('');
            }
            timerId = setTimeout(keepAlive, timeout);
        }
        function cancelKeepAlive() {
            if (timerId) {
                cancelTimeout(timerId);
            }
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`keepAlive()` следует добавить в конец `onOpen()` метода для webSocket
соединения и `cancelKeepAlive()` в конец `onClose()` метода.

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

Для примера, вместо этого…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var min = Math.min(a,b);
        A.push(v);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

…используйте это…
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var min = a < b ? a b;
        A[A.length] = v;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


44 – Не забывайте пользоваться инструментами по форматированию и стилистике кода.
Используйте JSLint и минимизацию (JSMin, для примера) перед тем, как код начнет жить.


45 – JavaScript просто шиииикааарен: Best Resources To Learn JavaScript.

Заключение


Естественно, есть множество советов и трюков и практик. Поэтому, если вам есть, что добавить, получить какую-то обратную связь или внести корректировки — пишите в комментариях.

Ссылочки


При написании данной статьи я использовал свои примеры для кода, однако некоторые примеры были навеяны из других статей и форумов:


А вот и сказочке конец....


Каждый по-разному может относиться к тому, что написано и изложено в этом материале. Достаточно он был хорош или нет, насколько глубоко раскрыты были вопросы, освещены результаты, насколько умны и интересны были примеры.
Моя задача, как транслятора, была в том, чтобы доставить его на суд говорящей, кипящей от работы синапсов общественности. А уж зачем ему конкретно это надо — каждый решает за себя.
Кто захочет поговорить с автором, почитать комментарии — пройдите по ссылочкам. Пробегитесь по оригинальной статье. Надеюсь, что моя скромная копия принесла вам пользы, не отняла много времени.

Спасибо за внимание!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Оригинал текста
Автор оригинального текста: Саад Муслики (Смотреть героя)
*Декабрь 23, 2013*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 34

    +1
    13 — String.prototype.trim есть еще не во всех браузерах, которые нужно поддерживать, увы.
    14 — А вот для сложения массивов есть Array#concat.
      0
      по 13 — для старых то да, а для новых то нет.
      по 14 — а тот не вернет новый массив разве?
        0
        Да, вернет.
        Там вот такой синтаксис:
        var a = [1, 2],
          b = [3, 4];
        
        a = a.concat(b);
        
          –2
          А в том, что Товарищ Муслики делает вроде как не — или я ошибаюсь?
            +1
            Да, там массив изменяется 'на месте'. Но, на мой взгляд, concat вещь более очевидная, чем push.apply
              –2
              Так то да — я сам в 9 из 10 сделаю `concat`, а про то, что вот `push.apply`…
        0
        13 — есть полифилы
        –1
        >>>Добавить один массив к другому
        concat?

        >>>isFinite(null); // true!!!
        Оо а вот этого не знал, спасибо
          –2
          Добавлю ещё один совет — как создать массив заданной длины, заполненный undefined:

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

          Стандартная операция «new Array (N)» вернёт пустой массив, так что тот же map с ним не сработает.
            0
            Хабрапарсер испортил 39 вариант. В комментарии к оригинальной статье указан исходник.
            +26
            О! Есть ещё такой трюк в 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, так что совет не в тему. И от того, что примитивы работают быстрее функций не значит, что все функции надо вручную разворачивать и писать каждый раз заново.

            Так что, статья — шлак.
              –3
              Было бы большим трюком, если автор прочел, хотя бы learn.javascript.ru.
              –4
              39. Нет лучшего HTML-escaper'а в браузере, чем сам браузер:
              var d = document.createElement("div"); 
              d.appendChild(document.createTextNode("this <b>is</b> html")); 
              return d.innerHTML;
              
                +5
                Создавать два дом-элемента просто чтобы эскейпнуть текст? Ну-ну)
                • UFO just landed and posted this here
                  • UFO just landed and posted this here
                      0
                      удалено
                      0
                      Я вообще слабо представляю зачем в браузере эскейпить текст, но если это всё-таки нужно, то на большом количестве вызовов мои дом-элемены делают вложенную функцию с регуляркой в разы.
                      Единственно, конечно, дом нужно создавать только один раз:
                      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
                      0
                      34. Эта микрооптимизация хорошо даёт эффекты в цикле в цикле в цикле (математические вычисления, например). Век оптимизирующих компиляторов не может это ускорить в общем виде. Тут такое дело что не может оптимизатор знать чего хотел разработчик. То есть length может поменяться внутри цикла и тогда поведение будет разным с оптимизацией из совета и без. А поменяться оно может крайне хитрыми методами, например если мы напишем в цикле всего лишь c += arr[i] — нельзя гарантировать что length остался прежним по той причине что теперь в js были добавлены геттеры и сеттеры. Мы могли особо упороться и сделать геттер на третий элемент массива, который добавит или уберёт что-то, или просто поменяет length.
                      • UFO just landed and posted this here
                      +1
                      Хоть я и вижу отрицательное отношение сообщества к статье, но посмею сказать, что статья мне понравилась.

                      Да, много банальщины и экономии на спичках. Но читая весь этот длинный список трюков, волей-неволей вспоминаешь некоторые вещи, которые уже подзабыл. И в этом «плюс» этой статьи.
                        –1
                        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.
                          0
                          п. 20 не ошибочен. Автор говорит об удалении из массива, а не объекта. Конструкцию for (key in object) не используют для перебора массива.
                            0
                            Автор говорит что delete заменяет элемент массива на undefined, но он этого не делает. Он ведёт себя точно так же. Он не знает что вот эта хрень перед ним массив.
                            0
                            Не несите ересь.
                            Дырявые массивы — зло как с точки зрения компилятора и оптимизации кода, так и понимания, например, такой фимозный случай — см. «Оптимизация 3».
                            Банально, но for in по массиву — зло. Он медленнее обычного for. Полифилы es5, es6, разные библиотеки могут расширить прототип массива, в ie8- нельзя сделать свойства неперечислимыми — эти свойства попадут в for in.
                              0
                              demark, rock: я не говорю что надо использовать эту конструкцию для перебора массива. Эта конструкция даёт реальные свойства объекта и показывает что delete действительно удалил элемент. Какие полифилы, зачем полифилы, getOwnProperty же. Я только хотел показать что элемент фактически пропал. В js всё является объектами и массивы в том числе. Использование delete делает всё правильно, оно не знает о том что эта штука делает вид что она массив. То есть Delete не схлопнет удалённый элемент, не уменьшит length, но сам key->value убьёт. Дырявый массив является злом только из-за того что в этом случае получается worst case scenario поиска ключа по хешу, но не более того.
                                0
                                Ошибочна только формулировка «не удаляет, а заменяет элемент на undefined», на фоне остальных, в числе которых полный трэш, совет один из самых адекватных. Вы же утверждаете, что «пункт ошибочен». «Использование delete делает всё правильно», но совсем не то, что нужно программисту. Видел трэш, где из массива удаляли элементы с помощью delete, добавляли с помощью push, перебирали с помощью .forEach и удивлялись, почему со временем код работает всё медленней.
                                  0
                                  Да, формулировка «в js всё является объектами» не менее ошибочна.
                                  • UFO just landed and posted this here
                              0
                              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 ) сделает то же самое нативно. Хотя выше это уже написали
                                0
                                Object.create появился только в ES5. Знать как написать naive polyfill вполне полезно.
                                +1
                                Number.toFixed возарвщает String, так что если вы хотите округлить, а не отформатировать, то правильнее пользоваться +num.toFixed(4)
                                — Надо быть очень аккуратным с перемешиванием массива используя numbers.sort(function(){ return Math.random() - 0.5});. Если он относительно большой то перемешан он будет более чем неравномерно. Примитивная мешалка массива из 10 элементов — идеально :)

                                Only users with full accounts can post comments. Log in, please.