Jak usunąć element z tablicy

varjs #17

W celu usunięcia elementu o danym indeksie w tablicy, używamy funkcji splice:

var arr = [1, 2, 3];
arr.splice(0, 1);
console.log(arr); // [2, 3]

Pierwszy argument oznacza numer indeksu, od którego chcemy zacząć operację usuwania, a drugi liczbę elementów, które chcemy usunąć. W powyższym przykładzie chcemy pozbyć się jednego elementu, poczynając od indeksu 0.

Warto dodać, że funkcja ta zwraca tablicę elementów, które usunęliśmy:

var arr = [3, 4, 6];
console.log(arr.splice(2, 1)); // [6]

Function.length vs arguments.length

lukas #16

Obiekt Function w JavaScript posiada własność length, która zwraca ilość oczekiwanych przez daną funkcję argumentów. Aby dowiedzieć się, ile argumentów zostało funkcji przekazanych, możemy użyć lokalnej dla danej funkcji zmiennej arguments:

var a = function(one, two, three, four) {
    return arguments.length;
};

a.length; // 4
a(1,2,3); // 3

Łączenie wartości tablic

lukas #15

Gdy chcemy dodać zawartość tablicy do końca drugiej, jest na to dość prosty sposób:

var a = ["raz", "dwa"];
var b = ["trzy", "cztery"];

Array.prototype.push.apply(a,b);

Wartości z tablicy b zostaną dodane do a:

console.log(a); // ["raz", "dwa", "trzy", "cztery"]

Unix Timestamp

lukas #14

Aby uzyskać czas unixowy w milisekundach, mierzony od 1 stycznia 1970 00:00:00 UTC, używamy:

new Date().getTime();

lub gdy nie zależy nam na starszych przeglądarkach:

Date.now();

Istnieje również skrócona, jednak mniej czytelna wersja:

+new Date;

Wartość NaN

varjs #13

Często w wyniku operacji arytmetycznych otrzymujemy wynik o wartości NaN. Skrót pochodzi od wyrażenia not a number. Wartość tę możemy dostać na przykład poprzez podzielenie liczby przez stringa:

var i = 10;
var result = i / "foobar";
console.log(result); // NaN

Jak więc sprawdzić, czy rezultalt to NaN, by uniknąć dalszych błędów w aplikacji? Można użyć funkcji isNaN:

isNaN(result); // true

Jest to problematyczne, o ile weźmiemy pod uwagę, że sprawdzana wartość będzie czymś innym niż NaN:

isNaN({}); // true

Można temu zaradzić definiując własną funkcję do sprawdzenia, czy zmienna to NaN. Otóż warto zauważyć, że NaN jako jedyna wartość nie daje prawdy przy porównaniu do samej siebie:

result === result; // false

Na tej podstawie konstruujemy własną funkcję sprawdzającą, alternatywną do isNaN:

var customIsNaN = function(i) {
	return i !== i;
}

Skrypty w <head> lub w <body> - różnice

varjs #12

Załóżmy, że dołączasz skrypty JavaScript w tradycyjny sposób, poprzez umieszczenie elementu <script> w <head>:

<head>
    <script src="main.js"></script>

Ta metoda ma jednak wady - opóźnia ona ładowanie stron w starszych przeglądarkach - browser czeka, dopóki załaduje się plik JavaScript, dopiero potem zaczyna renderować wszystko, co występuje po tagu <script>.

Jakie są alternatywy? Można użyć parametru async z HTML5, który pominie kolejność ładowania skryptów i załaduje je asynchronicznie:

<head>
    <script src="main.js" async="true"></script>

Warto też wiedzieć, że aby uniknąć oczekiwania i nie polegać na parametrze async, można również dołączyć swoje skrypty dopiero w <body> na samym końcu dokumentu HTML. Mamy wtedy pewność, że DOM jest załadowany i gotowy do użycia (a więc zapomnieć można o zdarzeniu DOMContentLoaded).

Więcej w temacie na MDN.

Losowa liczba z podanego zakresu

@vokiel #11

Czasami musimy wygenerować losową liczbę całkowitą z podanego zakresu. Niestety dostępna funkcja Math.random(); generuje liczby z przedziału 0-1. Własna implementacja funkcji rand może wyglądać tak:


function rand( min, max ){
    min = parseInt( min, 10 );
    max = parseInt( max, 10 );

    if ( min > max ){
        var tmp = min;
        min = max;
        max = tmp;
    }

    return Math.floor( Math.random() * ( max - min + 1 ) + min );
}

Kolejność parametrów w zasadzie nie ma znaczenia.

Zaprzyjaźnij się z operatorem porównania '==='

lydiawil #10

W innych językach programowania przeważnie porównujemy ze sobą elementy za pomocą podwójnego znaku równości '=='. Jednak ten operator nie uwzględnia typu porównywanych obiektów (JS próbuje przekształcić obiekty na wspólny typ), z czego może wyniknąć wiele nieoczekiwanych błedów w kodzie.

0 == "0" // => true
![] == [] // => true
undefined == null // => true

Dobrą praktyką jest używanie potrójnego znaku równości, który uwzględnia także typ porównywanych elementów. Pozwala to na wyeliminowanie z kodu wielu niejasności.

0 === "0" // => false
![] === [] // => false
undefined === null // => false

Jak sprawdzić, czy zmienna jest tablicą?

varjs #9

Sprawdzenie, czy zmienna jest tablicą było w JavaScript nie do końca prostym zadaniem. Niestety, typeof nie daje nam jednoznacznej odpowiedzi, ponieważ zwraca to samo dla tablic i obiektów:

var arr = [1, 2, 3];
var obj = {};
typeof arr; // "object"
typeof obj; // "object"

W ECMAScript 3 sprawdzaliśmy, czy zmienna jest tablicą następująco:

var arr = [1, 2, 3];
if (Object.prototype.toString.call(arr) === "[object Array]") {}

Na szczęście najnowsza wersja ECMAScript 5 wprowadza funkcję Array.isArray:

var arr = [1, 2, 3];
if (Array.isArray(arr)) {}

Tworzenie wewnętrznego scope

varjs #8

Dzięki automatycznemu wywoływaniu anonimowych funkcji możesz łatwo wprowadzić wewnętrzny scope zmiennych, dzięki czemu będą one dostępne tylko w tej funkcji.

(function() {
    var privateVar = 1;

})();
console.log(privateVar); // undefined

Zapomnij o jQuery, jest querySelector

varjs #7

Największą zaletą frameworka jQuery był łatwy sposób pobierania elementów drzewa DOM według selektorów CSS. Na przykład:

var news = $("div.news");

Ładowanie całego jQuery tylko dla takiej funkcjonalności jest często przerostem formy nad treścią. Z łatwością możesz skorzystać z document.querySelectorAll:

var news = document.querySelectorAll("div.news"); // wszystkie elementy div.news
var news = document.querySelector("div.news"); // tylko pierwszy element

Sprawdź wsparcie dla querySelector wśród współczesnych przeglądarek na canIUse.com.

Jak uzyskać pustą tablicę bez tworzenia nowej?

varjs #6

Załóżmy, że dysponujesz gotową tablicą i chcesz usunąć jej wszystkie elementy. Z reguły robi się to tak:

var arr = [1, 2, 3];
// ...
arr = [];

Jest to dobry pomysł, ale jeśli zależy nam na optymalizacji nawet tak trywialnego przypadku (sprawdza się to w kontekście developmentu gier, gdzie najlepiej zużywać jak najmniej pamięci) możemy skorzystać z właściwości length:

var arr = [1, 2, 3];
arr.length = 0;
console.log(arr); // []

W ten sposób korzystamy zawsze z tej samej struktury danych i przy okazji unikamy tworzenia nowej tablicy.

Największy i najmniejszy element w tablicy

varjs #5

Przyjmijmy, że mamy do czynienia z następującą tablicą:

var arr = [1, 2, 3];

Jak znaleźć jej największą wartość? Zapewne do głowy przychodzi Ci pętla i dodatkowa zmienna przechowująca aktualnie największy element. W JavaScript można to zrobić kompleksowo, przy pomocy Math.max:

var arr = [1, 2, 3];
Math.max.apply(null, arr); // 3

Podobnie da się zrobić z najmniejszą wartością, wykorzystując Math.min:

var arr = [1, 2, 3];
Math.min.apply(null, arr); // 1

JSLint Twoim przyjacielem

varjs #4

Bardzo popularnym rozwiązaniem pozwalającym sprawdzać poprawność kodu pod względem dobrych praktyk jest JSLint autorstwa Douglasa Crockforda.

Alternatywnym projektem dla JSLint jest... JSHint.

Oba projekty można użyć w systemach continuous integration, które mogą np. sprawdzać po każdym commicie, czy kod jest poprawny.

parseInt("08")

varjs #3

Pamiętaj, że parseInt traktuje stringa jako liczbę w systemie ósemkowym, jeśli na jego początku pojawi się "0". Dobrą praktyką jest umieszczanie zawsze "10" jako drugiego argumentu, który mówi, że powinniśmy sparsować liczbę w systemie dziesiętnym.

parseInt("08"); // 0
parseInt("08", 10); // 8

Tworzenie tablic i obiektów

varjs #2

Zapomnij o tworzeniu tablic i obiektów w, wydawałoby się, klasyczny sposób:

var arr = new Array();
var obj = new Object();

W JavaScript robi się to następująco:

var arr = [];
var obj = {};

JavaScript umożliwia tworzenie tych struktur natywnie, nie musimy dodatkowo wołać ich konstruktora. Poza tym można je nadpisać, co może przysporzyć dużo problemów:

var Object = null;

"for in" nie dla tablic

varjs #1

Pamiętaj, że pętle for in stworzone są tylko i wyłącznie do iteracji po obiektach:

var obj = { key : 1 };
for (var i in obj) {
    console.log(i); // "key"
}

For in używany z tablicami będzie iterował również przez własności .prototype tablicy, co jest efektem niepożądanym.