JavaScript

JavaScript porównywanie jednocześnie do null i undefined

Posted on Updated on

Wklepanie poniższych kommend wzróci takie wyniki jak w komentarzu po prawej

undefined == null; true
null == null; true
undefined != null; false
null != null; false
“” != null; true

Reasumując wystarczać mi na razie będzie porównanie “argument == null” gdy w rzeczywistości będę chciał sprawdzić “argument === undefined || argument === null”
działa to też dla odwrotnego operator, czyli napiszę “argument != null” zamiast pisać “argument !== undefined && argument !== null”

Sprytny czytelnik zauważy że ta rzecz powinna też działać gdy “argument == undefined” i ma rację. Ja jednak na razie zostaję przy porównywaniu do nulla.

Update

Gdy próbowałem sięgać pamięcią do tej wiedzy to wydawało mi się że ta rzecz dzieje się w TypeScript-cie, okazało się jednak, że to czysty JS i można go np używać również wewnątrz markupu w angularze.

Advertisements

Czytelność kodu/nazw – przykłady

Posted on Updated on

Taki przykład w javascript(typescript):

private deepClone(item) {
    return jQuery.extend(true, {}, item);
}

to że akurat deep copy zrobi “jQuery.extend(true, {}, item)” to implementacja. Myśląc “implementacja” myślę “szczegół implementacyjny”, a dalej myślę i traktuję to jako “szczegół”. Czytając metodę która coś tam robi (akurat tutaj zmienia relację parent-child na indeksy, zeby klonowanie nie miało cykli, klonuje delikwenta i ustatwia z powrotem relacje), wystarczy nam wiedza że robimy “deepClone”. Nie tylko wystarczy, ale większa wiedza byłaby szkodliwa.

private changeParentRelationsToIds(item: ItemViewModel): ItemViewModel {
    // Cloned data must be without parent and children relations but must be added again after copy finishes
    let parent = item.parent;
    let children = item.children;

    item.parentId = this.changeToNullIfParentIsRoot(item.parent.id);
    item.parent = undefined;
    item.children = [];

    let clonedItem = this.deepClone(item);

    item.parent = parent;
    item.children = children;

    return clonedItem;
}

Przytoczona tutaj implementacja deepCopy nie jest jedyną. http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object to pytanie na SO ma 3 tysiące łapek w górę i jest o czym dyskutować w odpowiedziach i komentarzach. W innym kontekście mógłbym użyć innej implementacji bo aktualna nie działa. A ja nie chcę o tym wszystkim wiedzieć, w mojej metodzie robiącej coś konkretnego chcę wywołać:

let clonedItem = this.deepClone(item);

JSFiddle na problemy z JavaScriptem, Angularem, TypeScriptem

Posted on Updated on

https://jsfiddle.net (i także wiele podobnych tooli/serwisów) jest edytorem w przeglądarce który pozwala odpalić nasz kod napisany w JavaScripcie. Takich tooli jest o wiele więcej dla różnych języków itp, ja skupie się na tym jednym i go opiszę, może są nawet lepsze alternatywy – nie wiem, widzę jednak, że jest najbardziej popularny na StackOverflow.

Składa się z 3 okienek gdzie wpisujemy nasz kod (html, JavaScript, css) oraz czwartego (output) w którym się uruchomi nasz kod:
jsfiddle example panes

Obecnie pozwala wybrać z kilku języków: JavaScript, CoffeeScript, JavaScript 1.7, Babel, TypeScript. Do tego kilkadziesiąt frameworków JS, z tego te bardziej popularne w kilku wersjach, np Angular jest w 4, a jQuery w ok. 20. To jest tylko takie ułatwienie, a nie ograniczenie. Dowolną bibliotekę można też dociągnąć tak jak includujemy każdy nowy scrypt w markupie html.

Debugowanie

Przyda się gdy coś “nie działa”

Najpierw samemu trzeba wyczerpać możliwości, bo często problem leży gdzieś u nas i widząć czysty kod, który działa w JSFiddle mamy pewność że to podejście działa tylko u nas czegoś jeszcze brakuje (gryzą sie zależności, czegoś brakuje, itp, itd). Jeśli już uruchomiliśmy w JSFiddle i nie działa tak jak powinno to wtedy mamy gotowy materiał na pytanie na StackOverflow. Nie możemy oczekiwać że obcy ludzie będą nam pomagać jeśli najpierw sami sobie nie pomogliśmy. Jeśli wrzucimy linka z kodem do uruchomienia na JSFiddle to każdy może na własne oczy zobaczyć co jest grane. I na przykład odpowiedzieć nam poprawioną wersją kodu.

Historia zmian

Nasz kod możemy wersjonować lub forkować, nawet bez zalogowania się.

Double vs single quotes – jakie ciapki w TypeScript/JavaScript

Posted on

W HTMLu zawsze podwójne:

href="/edit/2" class="btn btn-primary"

W JSON zawsze podwójne:

{name: "Marek"}

Chyba będę w JS poczytał z pojedynczych. Większość przykładów i kodu który ściągam korzysta właśnie z pojedynczych cudzysłowów (ciapków).
Dzięki temu też można w takich pojedynczych ciapkach pisać kod html który będzie miał podwójne ciapki:

let element = '<div class="wide"><a href="/edit">Edit</a></div>';

Jak to rozwiązał team rozwijający TypeScripta

Why use double quotes for strings
i dwie najciekawsze odpowiedzi:

But to specifically answer your question, we occasionally work in languages other than TypeScript. All those languages either require double quotes for strings (e.g. C#, C++, F#) or at least allow double quotes for strings (e.g. Python, Ruby). It’s easier not to ask people to shift their muscle memory when switching back and forth between languages.

One of the most common head-scratching problems with JSON is “why can’t my JSON file be parsed?” and an hour later you’ll find out single-quoted strings aren’t part of the JSON standard.

So double quotes have the least cognitive burden for us on the team. Hope that answers your question!

we decided to ban single quotes after a day of full text searching for
“width” in code and not being able to find it because it was written ‘width’

Niuanse JavaScript (zaliczone problemy)

Posted on Updated on

Na bazie doświadczeń z Agnularem 1.x

Wszystkie url kierujące do przeglądarki (np WebApi, linki) powinny się rozpoczynać od slasha (‘/’)

Markup który się wygeneruje w danej kolumnie przy korzystaniu z DataTables:

"render": function (data) {
    return '<a href="/items/' + data + '">' + data + '</a>';
}

Jeśli zapomnimy o slashu (href=”items/’ …) a jesteśmy na stronie localhost:8080/users to jedne przegląrki wygenerują adres localhost:8080/items/4 a inne (IE – może tylko w niektórych wersjach) wygenerują adres localhost:8080/users/items/4.

Podobnie przy odpytywaniu api:

P
$http.get('/api/items').success( // ...

Bezpieczne usuwanie elementu z tablicy w JavaScript

Posted on

Tak wyglądał mój kod, gdy dotychczas chciałem usunąć element z kolekcji.

elements.splice(array.indexOf(element), 1);

Niestety brakowało sprawdzania czy element rzeczywiście jest w tej tablicy. Czasem powiem wydaje się ze jest, a nie jest 😉 Najprostsza sytuacja, z którą sam się zderzyłem to zamiast elementu miałem idealną kopię elementu (angular.copy() w Angularze). W takim wypadku array.indexOf() zwróci sensowne -1. Bolało będzie za chwilę, gdy wykona się

elements.splice(-1, 1);

Taki kod usunie ostatni element. Ten minus sprawia, że index od którego zaczniemy usuwać będzie obliczany od końca tablicy. W tym przypadku usunięty zostanie ostatni element. Usunięcie niewłaściwego elementu może zamaskować problem. Ja stworzyłem sobie helpera:

function safeRemove(array, element) {
    var index = array.indexOf(element);
    if(index > -1){
        array.splice(index, 1);
    }
}

Przykład kodu, który zreprodukuje problem, który mi się przytrafił

var people = [
    { name: "Pawel" },
    { name: "Gawel" },
];
var person = people[0];

// some code

// in the meanwhile we get a copy
person = { name: person.name };

// some code

people.splice(people.indexOf(person), 1);

console.log(people[0].name); // Pawel 
// but we have deleted Pawel, haven't we?

Inspiracja dla wpisu

Własne błędy & Remove specific element from an array?

Generowanie klas C# na podstawie JSONa

Posted on

Aktualnie mam projekt, który jest praktycznie w całości w JavaScript (dokładnie AngularJS). Nie miał na początku być aż taki, wydawało mi się, że zdecydowanie więcej funkcjonalności wylądauje w back-endzie. Wszystkie modele są po stronie JS. Celowo, ponieważ nie chciałem utrzymywać modeli i DTO’s tutaj i tutaj.

Pojawiła się jednak potrzeba żeby mieć twardo typowaną strukturę danych po stronie C#. Z pomocą przyszło proste narzędzie json2csharp/.

Moja potrzeba modeli po stronie C# ogranicza się tylko do jednego przypadku więc uprościłem sobie sposób wrzucania tych klas. Wszystkie ok. 20 wygenerowanych klas wylądowało w jednym pliku. Nie przejmowałem się że niektóre klasy są nadmiarowe, np. mogłoby być:

public Address HomeAddress;
public Address WorkAddress;

a było:

public HomeAddress HomeAddress;
public WorkAddress WorkAddress;

Najważniejsze że szybko uzyskałem dostęp do obiektów.