-
1. Data: 2015-09-20 11:57:51
Temat: Javascript - jak tworzyć obiekty w strict mode?
Od: Marek <p...@s...com>
Witam,
Mam problem w realizacji prywatnych funkcji w strict mode. Oto kod:
"use strict";
function test()
{
var x=5;
var test3=function()
{
console.log(this,x);
};
var test2=function()
{
console.log(this,x);
test3();
};
test2();
test2.call(this);
}
costam=new test();
Operator this nie jest dostępny w test2 przy wywołaniu test2() ale jest
dostępny przy wywołaniu test2.call(this). Wartość X zawsze jest
poprawnie widziana więc test2 w obu przypadkach działa w obrębie obiektu
test.
Jeśli wywołamy test2 bez "call" to z poziomu test2 nie będziemy w stanie
wywołać metody test3 tak aby był widoczny w niej operator this.
W/g tego przykładu, strict mode może zatem prowadzić do usterek, które
nie ujawnią się podczas walidacji kodu poprzez JSHint jak i działanie
funkcji zależy od sposobu jej wywołania. Aż prosi się o "tajemnicze"
błędy które programiście nie ujawnią się a użytkownikowi tak, bo wykonał
np. nieco odmienną akcję niż testerzy i ta sama funkcja raz zadziałała,
raz nie. Wydaje mi się iż musi istnieć jakaś inna składnia wywołań metod
prywatnych aby uniknąć takich problemów. Macie pomysły?
--
Pozdrawiam,
Marek
-
2. Data: 2015-09-20 18:05:14
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Borys Pogoreło <b...@p...edu.leszno>
Dnia Sun, 20 Sep 2015 11:57:51 +0200, Marek napisał(a):
> błędy które programiście nie ujawnią się a użytkownikowi tak, bo wykonał
> np. nieco odmienną akcję niż testerzy i ta sama funkcja raz zadziałała,
> raz nie. Wydaje mi się iż musi istnieć jakaś inna składnia wywołań metod
> prywatnych aby uniknąć takich problemów. Macie pomysły?
Mieszasz w zakresach widoczności funkcji. Zrób sobie na początku funkcji
test2(): var that = this; i już masz dostęp do "this" pod nową nazwą w
funkcjach zagnieżdżonych. Często znajdziesz taką konstrukcję w bibliotekach
JS.
--
Borys Pogoreło
borys(#)leszno,edu,pl
-
3. Data: 2015-09-20 18:27:54
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Marek <p...@s...com>
W dniu 2015-09-20 o 18:05, Borys Pogoreło pisze:
> Mieszasz w zakresach widoczności funkcji. Zrób sobie na początku funkcji
> test2(): var that = this; i już masz dostęp do "this" pod nową nazwą w
> funkcjach zagnieżdżonych. Często znajdziesz taką konstrukcję w bibliotekach
> JS.
To nie zadziała. Rozwiązanie jakie przytaczasz jest raczej związane z
nie-strict-mode. Problem w tym, że this = null w metodzie test2
Co ciekawe - w "klasie" test() operator this nie jest nullem.
Przynajmniej pod Edge to obserwuję.
--
Pozdrawiam,
Marek
-
4. Data: 2015-09-20 18:48:12
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Marek <p...@s...com>
W ogóle jest coś nie tak:
function testClass(_data)
{
var data=_data;
testClass.prototype.read=function()
{
console.log("read",data);
};
}
aaa=new testClass(10);
aaa.read();
bbb=new testClass(20);
aaa.read();
daje wynik
10
20
Wygląda na to, że zmienna data staje się globalną z punktu widzenia
testClass!! O co tu chodzi? Albo mnie coś przyćmiło, albo coś porządnie
szwankuje w strict mode.
--
Pozdrawiam,
Marek
-
5. Data: 2015-09-20 21:53:25
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Borys Pogoreło <b...@p...edu.leszno>
Dnia Sun, 20 Sep 2015 18:27:54 +0200, Marek napisał(a):
>> Mieszasz w zakresach widoczności funkcji. Zrób sobie na początku funkcji
>> test2(): var that = this; i już masz dostęp do "this" pod nową nazwą w
>> funkcjach zagnieżdżonych. Często znajdziesz taką konstrukcję w bibliotekach
>> JS.
>
> To nie zadziała. Rozwiązanie jakie przytaczasz jest raczej związane z
> nie-strict-mode. Problem w tym, że this = null w metodzie test2
> Co ciekawe - w "klasie" test() operator this nie jest nullem.
SOA#1
> Przynajmniej pod Edge to obserwuję.
Weź wyłącz ten badziew, same problemy z tym Edge.
--
Borys Pogoreło
borys(#)leszno,edu,pl
-
6. Data: 2015-09-20 21:55:21
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Borys Pogoreło <b...@p...edu.leszno>
Dnia Sun, 20 Sep 2015 18:48:12 +0200, Marek napisał(a):
> Wygląda na to, że zmienna data staje się globalną z punktu widzenia
> testClass!! O co tu chodzi? Albo mnie coś przyćmiło, albo coś porządnie
> szwankuje w strict mode.
Nic się nie staje globalne. Modyfikujesz prototyp, ale wywołanie i tak
operuje na instancji obiektu, która ma zmienną lokalną.
--
Borys Pogoreło
borys(#)leszno,edu,pl
-
7. Data: 2015-09-21 11:43:23
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Marek <p...@s...com>
W dniu 2015-09-20 o 21:55, Borys Pogoreło pisze:
> Nic się nie staje globalne. Modyfikujesz prototyp, ale wywołanie i tak
> operuje na instancji obiektu, która ma zmienną lokalną.
Czy nie zauważyłeś, że instancja bbb zmodyfikowała zmienną data w
instancji aaa? Zmienna data nie jest w tym przypadku lokalną bo
przyjmuje wartość wspólną dla wszystkich instancji - zachowuje się
globalnie.
Nie rozumiem zatem dlaczego jedna instancja widzi wartości zmiennych
(prywatnych) drugiej instancji? Jak zatem spowodować aby poszczególne
instancje nie zakłócały siebie nawzajem?
Metodą prób i błędów odkryłem, że drobna modyfikacja deklaracji funkcji:
function testClass(_data)
{
var data=_data;
this.read=function()
{
console.log("read",data);
};
}
aaa=new testClass(10);
aaa.read();
bbb=new testClass(20);
aaa.read();
powoduje, że teraz odczyt będzie zupełnie inny:
10
10
Czyli instancja bbb nie zmodyfikowała zmiennej data w instancji aaa.
Dlaczego? Zmienna jest identycznie przecież zadeklarowana. Dlaczego
sposób zadeklarowania funkcji czytającej wpływa na zakres widoczności
zmiennej?
--
Pozdrawiam,
Marek
-
8. Data: 2015-09-21 13:36:44
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Marek <p...@s...com>
P.S.
Rozpocznę nowy wątek. Nieco inaczej sformułuję pytanie w nim. Zależy mi
na Twoim komentarzu.
-
9. Data: 2015-09-27 18:46:03
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: Borys Pogoreło <b...@p...edu.leszno>
Dnia Mon, 21 Sep 2015 11:43:23 +0200, Marek napisał(a):
> W dniu 2015-09-20 o 21:55, Borys Pogoreło pisze:
>
>> Nic się nie staje globalne. Modyfikujesz prototyp, ale wywołanie i tak
>> operuje na instancji obiektu, która ma zmienną lokalną.
>
> Czy nie zauważyłeś, że instancja bbb zmodyfikowała zmienną data w
> instancji aaa? Zmienna data nie jest w tym przypadku lokalną bo
> przyjmuje wartość wspólną dla wszystkich instancji - zachowuje się
> globalnie.
Tak, teraz widzę. Ale ogólnie to strasznie naciągnąłeś możliwości języka i
nic dziwnego, że Ci cuda wychodzą :) Na pewno przez takie zdefiniowanie
prototypu powodujesz, że jego zakres widoczności sięga do granic funkcji i
przez to zmienna "data" jest widoczna, co nie znaczy że powinieneś do niej
sięgać. Z kolei modyfikacja prototypu jest współdzielona między obiektami
(choć tu jest parę zastrzeżeń).
Teraz zgaduję - zapewne w prototypie ustawiana jest referencja na zmienną
data, przez co jej wartość jest nadpisana w drugim wywołaniu testClass()
(tu by się jednak przydała opinia kogoś, kto na JS zjadł sobie zęby).
Zamiast takich kombinacji możesz zrobić getter getData() w obiekcie
testClass lub po prostu zapisuj od razu do własności obiektu, czyli
this.data = _data. Gdybyś wyrzucił definiowanie prototypu poza funkcję, to
w ogóle by nie doszło do takiej sytuacji.
--
Borys Pogoreło
borys(#)leszno,edu,pl
-
10. Data: 2015-09-28 09:02:36
Temat: Re: Javascript - jak tworzyć obiekty w strict mode?
Od: n...@t...net.pl
W dniu poniedziałek, 21 września 2015 11:43:25 UTC+2 użytkownik Marek napisał:
> W dniu 2015-09-20 o 21:55, Borys Pogoreło pisze:
>
> > Nic się nie staje globalne. Modyfikujesz prototyp, ale wywołanie i tak
> > operuje na instancji obiektu, która ma zmienną lokalną.
>
> Czy nie zauważyłeś, że instancja bbb zmodyfikowała zmienną data w
> instancji aaa? Zmienna data nie jest w tym przypadku lokalną bo
> przyjmuje wartość wspólną dla wszystkich instancji - zachowuje się
> globalnie.
>
> Nie rozumiem zatem dlaczego jedna instancja widzi wartości zmiennych
> (prywatnych) drugiej instancji? Jak zatem spowodować aby poszczególne
> instancje nie zakłócały siebie nawzajem?
>
> Metodą prób i błędów odkryłem, że drobna modyfikacja deklaracji funkcji:
>
> function testClass(_data)
> {
> var data=_data;
>
> this.read=function()
> {
> console.log("read",data);
> };
> }
>
> aaa=new testClass(10);
> aaa.read();
> bbb=new testClass(20);
> aaa.read();
>
> powoduje, że teraz odczyt będzie zupełnie inny:
> 10
> 10
>
> Czyli instancja bbb nie zmodyfikowała zmiennej data w instancji aaa.
> Dlaczego? Zmienna jest identycznie przecież zadeklarowana. Dlaczego
> sposób zadeklarowania funkcji czytającej wpływa na zakres widoczności
> zmiennej?
>
>
> --
> Pozdrawiam,
> Marek
Według spisu instrukcji piszą, że "prototype" daje możliwość
zewnętrznego (zwracam uwagę na - zewnętrznego), a ja dodam sztucznego,
dodawania właściwości do istniejącego bytu (funkcja/klasa).
U ciebie jest to wewnątrz czyli nie za bardzo dobrze.
Skoro zewnętrznego to ta zmienna/właściwość jest/musi być już publiczna.
Ale rzeczywiście niech wypowie się ktoś bardziej wtajemniczony.
Andrzej.