diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md index 0534202a8..b07995788 100644 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md +++ b/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md @@ -1,6 +1,6 @@ -**Error**! +**Błąd**! -Try it: +Sprawdź ten kod: ```js run let user = { @@ -8,22 +8,21 @@ let user = { go: function() { alert(this.name) } } -(user.go)() // error! +(user.go)() // błąd! ``` +W większości przeglądarek wiadomość o błędzie nie zawiera zbyt wielu szczegółów mówiących co poszło nie tak. -The error message in most browsers does not give us much of a clue about what went wrong. +**Błąd wystąpił ponieważ nie ma średnika po `user = {...}`.** -**The error appears because a semicolon is missing after `user = {...}`.** - -JavaScript does not auto-insert a semicolon before a bracket `(user.go)()`, so it reads the code like: +JavaScript nie wstawia automatycznie średnika przed nawiasem `(user.go)()`, więc czyta kod w ten sposób:' ```js no-beautify let user = { go:... }(user.go)() ``` -Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error. +Teraz widzimy, że taka składnia jest w zasadzie wywołaniem obiektu `{ go: ... }` jako funkcji z argumentem `(user.go)`. W dodatku wywołanie to znajduje się w tej samej linijce co `let user`, więc obiekt `user` nie został jeszcze nawet zdefiniowany, dlatego pojawia się błąd. -If we insert the semicolon, all is fine: +Jeśli wstawimy średnik, kod będzie działać: ```js run let user = { @@ -34,4 +33,4 @@ let user = { (user.go)() // John ``` -Please note that brackets around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters. +Miej na uwadze, że nawiasy wokół `(user.go)` nie mają tu żadnego znaczenia. Zazwyczaj służą do zachowania kolejności wykonywania działań, jednak w tym przypadku kropka `.` i tak ma pierwszeństwo. Jedynie średnik jest tu niezbędny. diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md index f40d68735..e132e63c4 100644 --- a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md +++ b/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md @@ -2,9 +2,9 @@ importance: 2 --- -# Syntax check +# Sprawdzenie składni -What is the result of this code? +Jaki będzie rezultat wykonania tego kodu ? ```js no-beautify @@ -16,4 +16,4 @@ let user = { (user.go)() ``` -P.S. There's a pitfall :) +P.S. Jest tu pułapka :) diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md index 89bc0d722..8875bd388 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/3-why-this/solution.md @@ -1,22 +1,21 @@ -Here's the explanations. +Oto wyjaśnienie. -1. That's a regular object method call. +1. Jest to zwykłe wywołanie metody obiektu. -2. The same, brackets do not change the order of operations here, the dot is first anyway. +2. Tak jak powyżej, nawiasy nie zmieniają tutaj kolejności wykonywania działań, kropka i tak ma pierwszeństwo. -3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines: +3. Tutaj mamy bardziej złożone wywołanie `(expression).method()`. Wywołanie działa tutaj tak jakby było rozbite na dwie linijki kodu: ```js no-beautify - f = obj.go; // calculate the expression - f(); // call what we have + f = obj.go; // przypisanie jako wartość zmiennej + f(); // wywołanie stworzonej zmiennej ``` - Here `f()` is executed as a function, without `this`. + `f()` jest tutaj wywoływane jako funkcja, bez `this`. -4. The similar thing as `(3)`, to the left of the dot `.` we have an expression. +4. Podobna sytuacja jak w `(3)`, po lewej stronie od kropki `.` mamy wyrażenie. -To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type. - -Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`. +Żeby wyjaśnić zachowanie `(3)` i `(4)` musimy przypomnieć sobie, że akcesory właściwości (kropki lub nawiasy kwadratowe) zwracają wartość Typu Referencji. +Każda inna operacja niż wywołanie metody (jak przypisanie `=` lub `||`) zmienia Typ Referencji na zwykłą wartość, która nie zawiera informacji pozwalającej ustalić wartości `this`. diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/04-object-basics/04-object-methods/3-why-this/task.md index e2c073f62..3e9abe54a 100644 --- a/1-js/04-object-basics/04-object-methods/3-why-this/task.md +++ b/1-js/04-object-basics/04-object-methods/3-why-this/task.md @@ -2,11 +2,11 @@ importance: 3 --- -# Explain the value of "this" +# Określ wartość "this" -In the code below we intend to call `obj.go()` method 4 times in a row. +W poniższym kodzie chcemy wywołać metodę `obj.go()` cztery razy pod rząd. -But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why? +Jednak wywołania `(1)` i `(2)` działają inaczej niż `(3)` i `(4)`. Dlaczego? ```js run no-beautify let obj, method; diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index c1aaf4f97..c09c407a4 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -1,6 +1,6 @@ -**Answer: an error.** +**Odpowiedź: błąd.** -Try it: +Uruchom ten kod: ```js run function makeUser() { return { @@ -14,26 +14,26 @@ let user = makeUser(); alert( user.ref.name ); // Error: Cannot read property 'name' of undefined ``` -That's because rules that set `this` do not look at object definition. Only the moment of call matters. +Jest to spowodowane tym, że reguły ustalające wartość `this` nie uwzględniają faktu istnienia obiektu. Znaczenie ma tylko moment wywołania. -Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method with "dot" syntax. +Wartość `this` wewnątrz `makeUser()` jest `undefined`, ponieważ jest wywołana jako funkcja, a nie jako metoda wywołana za pomocą "kropki". -The value of `this` is one for the whole function, code blocks and object literals do not affect it. +Wartość `this` jest tu ustalona wyłącznie dla tej funkcji. Bloki kodu i obiekty nie są w tym przypadku brane pod uwagę. -So `ref: this` actually takes current `this` of the function. +Zatem `ref: this` jest równoznaczne z `this` funkcji. -We can rewrite the function and return the same `this` with `undefined` value: +Możemy napisać tę funkcję od nowa w taki sposób, że będzie zwracała takie samo `this` z wartością `undefined`: ```js run function makeUser(){ - return this; // this time there's no object literal + return this; // tym razem nie jest zwracany obiekt } alert( makeUser().name ); // Error: Cannot read property 'name' of undefined ``` -As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example. +Jak widzisz wynik `alert( makeUser().name )` jest taki sam jak wynik `alert( user.ref.name )` z poprzedniego przykładu. -Here's the opposite case: +A tutaj odwrotna sytuacja: ```js run function makeUser() { @@ -52,4 +52,4 @@ let user = makeUser(); alert( user.ref().name ); // John ``` -Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`. +Teraz kod działa prawidłowo, ponieważ `user.ref()` jest metodą, a wartością `this` jest obiekt przed kropką `.`. diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 4784b082c..dd9630e08 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Using "this" in object literal +# "this" w obiektach -Here the function `makeUser` returns an object. +Poniższa funkcja `makeUser` zwraca obiekt. -What is the result of accessing its `ref`? Why? +Jaki będzie rezultat dostępu do jego `ref`? I dlaczego? ```js function makeUser() { @@ -18,6 +18,6 @@ function makeUser() { let user = makeUser(); -alert( user.ref.name ); // What's the result? +alert( user.ref.name ); // Jaki będzie wynik? ``` diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index aa22608ec..2767dd32e 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Create a calculator +# Stwórz kalkulator -Create an object `calculator` with three methods: +Stwórz obiekt `calculator` z trzema metodami: -- `read()` prompts for two values and saves them as object properties. -- `sum()` returns the sum of saved values. -- `mul()` multiplies saved values and returns the result. +- `read()` pobiera dwie wartości z okienek dialogowych `prompt` i zachowuje je jako właściwości obiektu. +- `sum()` zwraca sumę zachowanych wartości. +- `mul()` mnoży zachowane wartości i zwraca wynik. ```js let calculator = { - // ... your code ... + // ... twój kod ... }; calculator.read(); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 2b47873fc..4818745a1 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,4 +1,4 @@ -The solution is to return the object itself from every call. +Rozwiązaniem jest zwracanie obiektu z każdej funkcji. ```js run demo let ladder = { @@ -26,7 +26,7 @@ let ladder = { ladder.up().up().down().up().down().showStep(); // 1 ``` -We also can write a single call per line. For long chains it's more readable: +Przy długich łańcuchach kodu, możemy każdy człon umieszczać w osobnej linijce, dla zwiększenia czytelności: ```js ladder diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index eca9f4e92..5cf9d59a3 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -2,9 +2,9 @@ importance: 2 --- -# Chaining +# Łączenie -There's a `ladder` object that allows to go up and down: +Mamy tutaj obiekt `ladder` który pozwala wspinać się do góry i schodzić w dół: ```js let ladder = { @@ -15,13 +15,13 @@ let ladder = { down() { this.step--; }, - showStep: function() { // shows the current step + showStep: function() { // pokazuje aktualną wartość step alert( this.step ); } }; ``` -Now, if we need to make several calls in sequence, can do it like this: +Jeśli chcielibyśmy wykonać sekwencję ruchów, możemy zrobić to w ten sposób: ```js ladder.up(); @@ -30,10 +30,10 @@ ladder.down(); ladder.showStep(); // 1 ``` -Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this: +Zmodyfkuj kod dla `up`, `down` i `showStep` żeby można było połączyć wywołania metod, w taki sposób: ```js ladder.up().up().down().showStep(); // 1 ``` -Such approach is widely used across JavaScript libraries. +Wiele bibliotek JavaScript wykorzystuje taki sposób pisania kodu. diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 2dda938d7..5e20f8d5c 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -1,6 +1,6 @@ -# Object methods, "this" +# Metody obiektów, "this" -Objects are usually created to represent entities of the real world, like users, orders and so on: +Obiekty zazwyczaj są tworzone po to, żeby przedstawiać rzeczywiste byty, takie jak użytkownicy, zadania do wykonania i tym podobne: ```js let user = { @@ -9,13 +9,13 @@ let user = { }; ``` -And, in the real world, a user can *act*: select something from the shopping cart, login, logout etc. +I tak jak w rzeczywistości, użytkownik może *działać*: wybrać coś z koszyka, zalogować się, wylogować itd. -Actions are represented in JavaScript by functions in properties. +Czynności w JavaScript'cie są funkcjami we właściwościach obiektu. -## Method examples +## Przykłady metod -For a start, let's teach the `user` to say hello: +Na początek, nauczmy użytkownika `user` przywitania się: ```js run let user = { @@ -25,22 +25,22 @@ let user = { *!* user.sayHi = function() { - alert("Hello!"); + alert("Cześć!"); }; */!* -user.sayHi(); // Hello! +user.sayHi(); // Cześć! ``` -Here we've just used a Function Expression to create the function and assign it to the property `user.sayHi` of the object. +Właśnie stworzyliśmy funkcję za pomocą Wyrażenia Funkcji i przypisaliśmy ją do właściwości `user.sayHi` obiektu. -Then we can call it. The user can now speak! +Następnie ją wywołaliśmy i nasz użytkownik potrafi teraz mówić! -A function that is the property of an object is called its *method*. +Funkcję, która jest właściwością obiektu nazywamy *metodą*. -So, here we've got a method `sayHi` of the object `user`. +Także mamy tutaj metodę `sayHi` obiektu `user`. -Of course, we could use a pre-declared function as a method, like this: +Oczywiście, moglibyśmy również posłużyć się zadeklarowaną wcześniej funkcją jako metodą: ```js run let user = { @@ -48,61 +48,62 @@ let user = { }; *!* -// first, declare +// najpierw deklarujemy function sayHi() { - alert("Hello!"); + alert("Cześć!"); }; -// then add as a method +// następnie dodajemy jako metodę user.sayHi = sayHi; */!* -user.sayHi(); // Hello! +user.sayHi(); // Cześć! ``` ```smart header="Object-oriented programming" -When we write our code using objects to represent entities, that's called [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". +Kiedy piszemy kod wykorzystujący obiekty do reprezentowania różnych istnień, nazywamy to [programowaniem obiektowym](https://pl.wikipedia.org/wiki/Programowanie_obiektowe), w skrócie: +"OOP". -OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more. +OOP to bardzo rozległy i interesujący temat. Jak wybrać właściwe podmioty? Jak stworzyć zależności między nimi? Jest to cała architektura i istnieje wiele świetnych książek traktujących ten temat, jak np. "Wzorce projektowe. Elementy oprogramowania" autorstwa E.Gamma, R.Helm, R.Johnson, J.Vissides, lub "Object-Oriented Analysis and Design with Applications" G.Booch, i wiele innych. ``` -### Method shorthand +### Skrót składniowy dla metod -There exists a shorter syntax for methods in an object literal: +Istnieje skrócona składnia dla metod w literałach obiektowych: ```js -// these objects do the same +// poniższe obiekty działają tak samo user = { sayHi: function() { - alert("Hello"); + alert("Cześć"); } }; -// method shorthand looks better, right? +// skrócona składnia wygląda lepiej, prawda ? user = { *!* - sayHi() { // same as "sayHi: function()" + sayHi() { // to samo co "sayHi: function()" */!* - alert("Hello"); + alert("Cześć"); } }; ``` -As demonstrated, we can omit `"function"` and just write `sayHi()`. +Jak widzimy, możemy pominąć `"function"` i po prostu użyć `sayHi()`. -To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases the shorter syntax is preferred. +Prawde mowiąc, oba zapisy nie są całkowicie identyczne. Istnieją subtelne różnice między nimi, związane z dziedziczeniem (ten temat poruszymy później), ale na tem moment nie ma to znaczenia. W prawie każdym przypadku lepiej użyć krótszej składni. -## "this" in methods +## "this" w metodach -It's common that an object method needs to access the information stored in the object to do its job. +Często się zdarza, że metoda obiektu do poprawnego działania potrzebuje dostępu do informacji zawartej w tym samym obiekcie. -For instance, the code inside `user.sayHi()` may need the name of the `user`. +Dla przykładu, kod wewnątrz `user.sayHi()` może wymagać imienia użytkownika `user`. -**To access the object, a method can use the `this` keyword.** +**Aby zdobyć taki dostęp, metoda może wykorzystać słowo kluczowe `this`** -The value of `this` is the object "before dot", the one used to call the method. +Wartością `this` jest obiekt "przed kropką", który został wykorzystany do wywołania metody. -For instance: +Na przykład: ```js run let user = { @@ -111,7 +112,7 @@ let user = { sayHi() { *!* - // "this" is the "current object" + // "this" jest "aktualnym obiektem" alert(this.name); */!* } @@ -121,9 +122,9 @@ let user = { user.sayHi(); // John ``` -Here during the execution of `user.sayHi()`, the value of `this` will be `user`. +Podczas wywołania `user.sayHi()`, wartością `this` będzie `user`. -Technically, it's also possible to access the object without `this`, by referencing it via the outer variable: +Możliwe jest również uzyskanie dostępu do obiektu bez używania `this`, przez odwołanie się do niego za pomocą zmiennej z zewnątrz: ```js let user = { @@ -132,16 +133,16 @@ let user = { sayHi() { *!* - alert(user.name); // "user" instead of "this" + alert(user.name); // "user" zamiast "this" */!* } }; ``` -...But such code is unreliable. If we decide to copy `user` to another variable, e.g. `admin = user` and overwrite `user` with something else, then it will access the wrong object. +...Jednak na takim kodzie nie można polegać. Jeśli skopiujemy obiekt `user` do innej zmiennej, np `admin = user` i zmienimy wartości w zmiennej `user`, wtedy nasza metoda będzie się odwoływać do niewłaściwego obiektu. -That's demonstrated below: +Taki przykład przedstawiono poniżej: ```js run let user = { @@ -150,7 +151,7 @@ let user = { sayHi() { *!* - alert( user.name ); // leads to an error + alert( user.name ); // pojawi się błąd */!* } @@ -158,18 +159,18 @@ let user = { let admin = user; -user = null; // overwrite to make things obvious +user = null; // dla pewności nadpisujemy zmienną -admin.sayHi(); // Whoops! inside sayHi(), the old name is used! error! +admin.sayHi(); // Ups! wewnątrz sayHi(), wykorzystywana jest zła zmienna! Błąd! ``` -If we used `this.name` instead of `user.name` inside the `alert`, then the code would work. +Jeśli użylibyśmy `this.name` zamiast `user.name` wewnątrz `alert`, wtedy kod by zadziałał. -## "this" is not bound +## "this" nie jest powiązane -In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function. +W JavaScript słowo kluczowe `this` zachowuje się inaczej niż w innych językach programowania. Może ono być użyte w każdej funkcji. -There's no syntax error in the following example: +Zapis taki jak w poniższym przykładzie nie powoduje błędu: ```js function sayHi() { @@ -177,9 +178,9 @@ function sayHi() { } ``` -The value of `this` is evaluated during the run-time, depending on the context. +Wartość `this` jest określana podczas wykonywania kodu, zależnie od kontekstu. -For instance, here the same function is assigned to two different objects and has different "this" in the calls: +Na przykład tutaj ta sama funkcja jest przypisana do dwóch różnych obiektów i posiada różne "this" przy wywoływaniach: ```js run let user = { name: "John" }; @@ -190,23 +191,24 @@ function sayHi() { } *!* -// use the same function in two objects +// używamy tej samej funkcji w obu obiektach user.f = sayHi; admin.f = sayHi; */!* -// these calls have different this -// "this" inside the function is the object "before the dot" +// wywołania mają różne this +// "this" wewnątrz funkcji jest obiektem "przed kropką" user.f(); // John (this == user) admin.f(); // Admin (this == admin) -admin['f'](); // Admin (dot or square brackets access the method – doesn't matter) +admin['f'](); // Admin (kropka lub nawiasy kwadratowe udzielają dostępu do metody) ``` -The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above. +Zasada jest prosta: jeśli `obj.f()` jest wywołana, to `this` jest `obj` podczas wywoływania `f`. Więc w powyższym przykładzie jest to zarówno `user` lub `admin`. -````smart header="Calling without an object: `this == undefined`" -We can even call the function without an object at all: + +````smart header="Calling without an object: `this` == undefined" +Możemy wywołać tę funkcję nawet bez obiektu: ```js run function sayHi() { @@ -216,74 +218,75 @@ function sayHi() { sayHi(); // undefined ``` -In this case `this` is `undefined` in strict mode. If we try to access `this.name`, there will be an error. +W tym przypadku `this` jest `undefined` w trybie ścisłym. Jeśli spróbujemy uzyskać dostęp do `this.name` pojawi się błąd. -In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes. +Poza trybem ścisłym, w tym przypadku, wartością `this` będzie *obiekt globalny* (`window` w przeglądarce, dojdziemy do tego w późniejszym rozdziale [](info:global-object)). Jest to zamierzchłe zachowanie języka, które tryb `"use strict"` naprawia. -Usually such call is a programming error. If there's `this` inside a function, it expects to be called in an object context. +Zazwyczaj takie wywołanie jest błędem w kodzie. Jeśli w funkcji istnieje `this`, to powinna ona zostać wywołana jako metoda obiektu. ```` + ```smart header="The consequences of unbound `this`" -If you come from another programming language, then you are probably used to the idea of a "bound `this`", where methods defined in an object always have `this` referencing that object. +Jeśli programujesz w innym języku, zapewne przywykłeś do "powiązanego this", gdzie metoda zdefiniowana w obiekcie zawsze posiada `this` wskazujące na ten obiekt. -In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is "before the dot". +W JavaScript `this` jest "wolne", jego wartość jest określana podczas wykonywania kodu i nie zależy od tego gdzie została zadeklarowana metoda, tylko jaki obiekt znajduje się "przed kropką". -The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, the greater flexibility creates more possibilities for mistakes. +Koncepcja ewaluacji `this` podczas wykonywania kodu ma wady i zalety. Z jednej strony, funkcja może być wykorzystywana przez różne obiekty. Z drugiej - im większa swoboda, tym większe ryzyko pomyłki. -Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and avoid problems. +Naszym zadaniem nie jest ocena czy taki wybór przy tworzeniu języka był dobry czy zły. Zastanawiamy się raczej jak z takim mechanizmem pracować, jakie zyskać dzięki temu korzyści i jak uniknąć problemów. ``` -## Internals: Reference Type +## Internals: Referencje -```warn header="In-depth language feature" -This section covers an advanced topic, to understand certain edge-cases better. +```warn header="Zaawansowane szczegóły języka" +Ta część zawiera bardziej zaawansowaną terminologię, pomagającą lepiej zrozumieć skrajne przypadki. -If you want to go on faster, it can be skipped or postponed. +Jeśli chcesz szybciej przejść dalej, możesz pominąć tę część lub zostawić do przeczytania na później. ``` -An intricate method call can lose `this`, for instance: +Zawiła metoda może doprowadzić do zgubienia `this`, na przykład: ```js run let user = { name: "John", hi() { alert(this.name); }, - bye() { alert("Bye"); } + bye() { alert("Pa!"); } }; -user.hi(); // John (the simple call works) +user.hi(); // John (zwykłe wywołanie działa bez problemu) *!* -// now let's call user.hi or user.bye depending on the name -(user.name == "John" ? user.hi : user.bye)(); // Error! +// teraz warunkowo wywołajmy metodę user.hi lub user.bye w zależności od wartości name +(user.name == "John" ? user.hi : user.bye)(); // Błąd! */!* ``` -On the last line there is a conditional operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`. +W ostatniej linijce operator warunkowy wybiera pomiędzy `user.hi` i `user.bye`. W powyższym przykładzie wynikiem jest `user.hi`. -Then the method is immediately called with parentheses `()`. But it doesn't work correctly! +Następnie metoda jest natychmiast wywoływana z nawiasami `()`. Ale nie działa prawidłowo! -As you can see, the call results in an error, because the value of `"this"` inside the call becomes `undefined`. +Jak widzisz, wywołanie powoduje błąd, ponieważ wartość `"this"` wewnątrz metody staje się `undefined`. -This works (object dot method): +Ten kod działa (obiekt kropka metoda): ```js user.hi(); ``` -This doesn't (evaluated method): +Ten nie działa (metoda ewaluowana): ```js -(user.name == "John" ? user.hi : user.bye)(); // Error! +(user.name == "John" ? user.hi : user.bye)(); // Błąd! ``` -Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works. +Dlaczego? Jeśli chcemy zrozumieć dlaczego tak się dzieje, przyjrzyjmy się dokładnie jak działa wywołanie metody `obj.method()`. -Looking closely, we may notice two operations in `obj.method()` statement: +Patrząc uważne, możemy zaobserwować dwie wykonujące się operacje w `obj.method()`: -1. First, the dot `'.'` retrieves the property `obj.method`. -2. Then parentheses `()` execute it. +1. Najpierw, kropka `'.'` pobiera właściwość `obj.method`. +2. Następnie nawiasy `()` ją wywołują. -So, how does the information about `this` get passed from the first part to the second one? +Jak więc informacja o `this` migruje z pierwszej części do drugiej? -If we put these operations on separate lines, then `this` will be lost for sure: +Jeśli rozłożymy te operacje na oddzielne linie kodu, wartość `this` z pewnością zostanie zgubiona: ```js run let user = { @@ -292,44 +295,44 @@ let user = { } *!* -// split getting and calling the method in two lines +// podział pomiędzy pobraniem i wywołanie metody na oddzielne linie let hi = user.hi; -hi(); // Error, because this is undefined +hi(); // Błąd, ponieważ this jest undefined */!* ``` -Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`. +`hi = user.hi` przypisuje metodę do zmiennej, a na samym końcu jest wywoływana jako osobna funkcja, więc `this` nie posiada już tutaj żadnej wartości. -**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).** +**Żeby `user.hi()` działało prawidłowo, JavaScript używa sztuczki -- kropka `'.'` nie zwraca funkcji, tylko wartość ze specjalnym [Typem Referencji](https://tc39.github.io/ecma262/#sec-reference-specification-type).** -The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language. +Typ Referencji jest "typem specyfikacji". Nie możemy go bezpośrednio uzyć, ale jest on wbudowany i wykorzystywany przez język. -The value of Reference Type is a three-value combination `(base, name, strict)`, where: +Wartością Typu Referencji jest trójwartościowa kombinacja `(base, name, strict)`, gdzie: -- `base` is the object. -- `name` is the property name. -- `strict` is true if `use strict` is in effect. +- `base` jest obiektem. +- `name` jest nazwą właściwości. +- `strict` jest true jeśli używamy `use strict`. -The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is: +Wynikiem dostępu do właściwości `user.hi` nie jest funkcja, tylko wartość Typu Referencji. Dla `user.hi` w trybie ścisłym jest to: ```js // Reference Type value (user, "hi", true) ``` -When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`=user` in this case). +Jeśli wywołujemy nawiasy `()` na Typie Referencji, otrzymują one całą informację o obiekcie, jego metodzie i mogą ustawić dla this prawidłową wartość (w tym przypadku `=user`). -Reference type is a special "intermediary" internal type, with the purpose to pass information from dot `.` to calling parentheses `()`. +Typ Referencji jest specjalnym "pośrednim" typem wewnętrznym, którego zadaniem jest przekazywanie informacji z kropki `.` do nawiasów `()`. -Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`. +Każda inna operacja, jak przypisanie `hi = user.hi` odrzuca całkowicie Typ Referencji, bierze wartość z `user.hi` (funkcji) i przekazuje ją dalej. Zatem każda następna operacja "gubi" `this`. -So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind). +Podsumowując, wartość `this` jest przekazywane we właściwy sposób jeśli funkcja jest wywoływana za pomocą kropki `obj.method()` lub nawiasów kwadratowych `obj[`method`]()` (obie składnie zadziałają tutaj identycznie). W dalszej części kursu, nauczymy się różnych możliwości aby rozwiązać ten problem, takich jak [func.bind()](/bind#solution-2-bind). -## Arrow functions have no "this" +## Funkcje strzałkowe nie mają "this" -Arrow functions are special: they don't have their "own" `this`. If we reference `this` from such a function, it's taken from the outer "normal" function. +Funkcje strzałkowe są specjalnym typem funkcji: nie posiadają "własnego" `this`. Jeśli odnosimy się do `this` w takiej funkcji, jego wartość jest pobierana z zewnętrznej "normalnej" funkcji. -For instance, here `arrow()` uses `this` from the outer `user.sayHi()` method: +W poniższym przykładzie `arrow()` używa `this` z zewnętrznej metody `user.sayHi()`: ```js run let user = { @@ -343,18 +346,18 @@ let user = { user.sayHi(); // Ilya ``` -That's a special feature of arrow functions, it's useful when we actually do not want to have a separate `this`, but rather to take it from the outer context. Later in the chapter we'll go more deeply into arrow functions. +Jest to specjalna właściwość funkcji strzalkowych, są użyteczne gdy nie chcemy mieć osobnego `this`, tylko wolimy je pobrać z zewnątrz. W późniejszym rozdziale zagłębimy się bardziej w to czym są funkcje strzałkowe. -## Summary +## Podsumowanie -- Functions that are stored in object properties are called "methods". -- Methods allow objects to "act" like `object.doSomething()`. -- Methods can reference the object as `this`. +- Funkcje które są przechowywane w obiekcie nazywamy "metodami". +- Metody pozwalają obiektom "zachowywać się" w sposób `object.zróbCoś()` +- Metody mają referencje do swojego obiektu, jest to ich wartość `this` -The value of `this` is defined at run-time. -- When a function is declared, it may use `this`, but that `this` has no value until the function is called. -- A function can be copied between objects. -- When a function is called in the "method" syntax: `object.method()`, the value of `this` during the call is `object`. +Wartość `this` jest określana podczas wykonywania kodu. +- Kiedy funkcja jest deklarowana, może ona użyć `this`, z tym że nie będzie ono miało wartości tak długo aż funkcja zostanie wywyłana. +- Jedna funkcja może być użwana jako metoda przez kilka obiektów. +- Kiedy funkcja jest wykonywana za pomocą składni: `object.method()`, `this` podczas wykonywania przybierze wartość `object`. -Please note that arrow functions are special: they have no `this`. When `this` is accessed inside an arrow function, it is taken from outside. +Zapamiętaj że funkcje strzałkowe są specjalnym typem funkcji: nie posiadają `this`. Kiedy chcemy uzyskać dostęp do `this` wewnątrz funkcji strzałkowej, wartość jest brana z zewnątrz.