Thread View: pl.comp.lang.php
14 messages
14 total messages
Started by Marek S
Thu, 25 Jan 2018 19:19
Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Thu, 25 Jan 2018 19:19
Date: Thu, 25 Jan 2018 19:19
61 lines
2698 bytes
2698 bytes
Witam.
Mój wątek dotyczy JS ale można go uogólnić. Otóż kiedyś programowałem
aplikacje w C++ i nie tylko w tym języku. Zmienne prywatne występowały w
kodach jak tlen w powietrzu. Sporo obecnie programuję w PHP i JS. Przy
okazji edycji ECMA6 tego ostatniego języka zdumiały mnie dwie rzeczy:
1. Wprowadzono wreszcie pojęcie klas i dziedziczenia ale... zignorowano
zmienne prywatne. Nie ma czegoś takiego w samych założeniach.
2. Gdy na międzynarodowym forum zapytałem o potrzebę symulacji zmiennych
prywatnych, wywołałem konsternację. Uzyskiwałem odpowiedzi w stylu
przecież tak ma być, co tu kombinować! Argumentacja moja w postaci
takiej iż jeśli wszystkie zmienne będą publiczne w dziedziczonych
klasach i nadpiszą się niechcący (bo autor klasy B może nie wiedzieć
jakich nazw nie powinien używać aby nie nadpisać przypadkiem tych z
klasy bazowej A - gdy obie są rozwijane więc nowe zmienne będą się
pojawiać), uzyskałem odpowiedź iż: no jak to możliwe, przecież w
dokumentacji poszczególnych klas trzeba pisać jakich nazw nie używać.
Zilustruję problem za pomocą JS:
"use strict";
class aClass {
readFromA() {
console.log(this.a);
}
constructor() {
this.a = 5;
}
}
class bClass extends aClass {
readFromB() {
console.log(this.a);
}
constructor() {
super();
this.a=10;
}
}
let bc=new bClass();
bc.readFromA(); //pokaże 10
bc.readFromB(); //pokaże 10
Wynik nie zaskakuje a ja głupi uparłem się by obie klasy mogły mieć
swoją prywatną zmienną "a". Osiągnąłem to w końcu korzystając z faktu,
że w JS to co jest po extends może być ... wyrażeniem (!!!).
Czy też sądzicie, że zmienne prywatne to przeżytek?
--
Pozdrawiam,
Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Roman Tyczka
Date: Thu, 25 Jan 2018 20:29
Date: Thu, 25 Jan 2018 20:29
9 lines
984 bytes
984 bytes
On Thu, 25 Jan 2018 20:19:34 +0100, Marek S wrote: > Czy też sądzicie, że zmienne prywatne to przeżytek? Czy pisząc zmienne masz na myśli po prostu pola obiektu? -- pozdrawiam Roman Tyczka
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Thu, 25 Jan 2018 23:07
Date: Thu, 25 Jan 2018 23:07
23 lines
1405 bytes
1405 bytes
W dniu 25-01-2018 o 21:29, Roman Tyczka pisze:
> On Thu, 25 Jan 2018 20:19:34 +0100, Marek S wrote:
>
>> Czy też sądzicie, że zmienne prywatne to przeżytek?
>
> Czy pisząc zmienne masz na myśli po prostu pola obiektu?
>
Mam na myśli właściwości (properties).
Dla rozwiania wątpliwości przykład kawałka mojego kodu w PHP:
class tableProClass
{
private $rowCounter=0;
private $fnReplace, $fnConvert;
...
Czegoś takiego w klasach JS nie ma.
--
Pozdrawiam,
Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Roman Tyczka
Date: Fri, 26 Jan 2018 22:22
Date: Fri, 26 Jan 2018 22:22
30 lines
1819 bytes
1819 bytes
On Fri, 26 Jan 2018 00:07:59 +0100, Marek S wrote:
>>> Czy też sądzicie, że zmienne prywatne to przeżytek?
>>
>> Czy pisząc zmienne masz na myśli po prostu pola obiektu?
>>
>
> Mam na myśli właściwości (properties).
> Dla rozwiania wątpliwości przykład kawałka mojego kodu w PHP:
>
> class tableProClass
> {
> private $rowCounter=0;
> private $fnReplace, $fnConvert;
> ...
>
>
> Czegoś takiego w klasach JS nie ma.
Dopiero raczkuję w JS, ale jeśli rzeczywiście nie ma pól prywatnych
(property znam z Delphi i z czymś ciutkę innym mi się kojarzą) to w ogóle
nie ma mowy o pełnej obiektowości, bo wszak obiekt to zbiór pól z danymi i
metod do operowania na nich, dzięki czemu uzyskuje się jedną z
fundamentalnych cech OOP czyli enkapsulację. Bez prywatności nie ma
enkapsulacji, bo pola mogą być zmieniane poza logiką obiektu, a to prowadzi
do nieprzewidzianych sytuacji.
--
pozdrawiam
Roman Tyczka
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Sat, 27 Jan 2018 12:24
Date: Sat, 27 Jan 2018 12:24
96 lines
3875 bytes
3875 bytes
W dniu 26-01-2018 o 23:22, Roman Tyczka pisze:
>> Czegoś takiego w klasach JS nie ma.
>
> Dopiero raczkuję w JS, ale jeśli rzeczywiście nie ma pól prywatnych
> (property znam z Delphi i z czymś ciutkę innym mi się kojarzą)
W nomenklaturze JS zmienne jako cechy obiektów lub też quasiobiektów to
właściwości:
https://www.w3schools.com/js/js_properties.asp
Jest też gotowa metoda do ich tworzenia zawierająca "properties" w nazwie:
https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
> to w ogóle
> nie ma mowy o pełnej obiektowości, bo wszak obiekt to zbiór pól z danymi i
> metod do operowania na nich, dzięki czemu uzyskuje się jedną z
> fundamentalnych cech OOP czyli enkapsulację. Bez prywatności nie ma
> enkapsulacji, bo pola mogą być zmieniane poza logiką obiektu, a to prowadzi
> do nieprzewidzianych sytuacji.
O tym właśnie piszę. Zarówno standard JS (przynajmniej bieżący ECMA6)
jak i programiści uważają właściwości prywatne chyba jako oldschoolowe.
JS od dawna ogranicza się jedynie do rezerwacji słów kluczowych typu
private czy protected ale nic z tym nie robi. Programiści JS, jak wynika
z moich dyskusji, dziwią się, że coś takiego chcę używać.
Dla Twojej informacji: daje się symulować właściwości prywatne w klasach
ale wymaga to łamańców. W Googlach grzebałem ze 2 dni i nigdzie
przykładu poniższego nie znalazłem. Ja wykorzystuję do tego zmienne o
zasięgu bloku, które deklaruje się słowem kluczowym let (nie var).
Wykorzystuję też to, że klasę można rozszerzać nie tylko inną klasą, ale
również - uwaga - wynikiem działania funkcji!!! Trzecia rzecz, korzystam
z tzw słabych map lub symboli bo w JS właściwość nie musi być aresowana
stringiem, ale również .... obiektem!
Dopiero taki burdel w kodzie utworzy zmienną prywatną:
let aClass = (function () {
let a = Symbol("a");
class aClass {
readFromA() {
console.log(this[a], this.b);
}
constructor() {
this[a] = "aaa"; //this is private
this.b = "bbb"; // this is public
}
}
return aClass;
})();
let bClass = (function () {
let a = Symbol("a");
class bClass extends aClass {
readFromB() {
console.log("B", this[a], this.b);
}
constructor() {
super();
this[a] = "ccc"; //this is private
this.b = "ddd"; // this is public
}
}
return bClass;
})();
let bc = new bClass();
bc.readFromA(); // aaa ddd
bc.readFromB(); // ccc ddd
Wyrażenie "extends aClass" rozszerza klasę bClass o wynik działania
funkcji anonimowej, który jest przechowywany w zmiennej sugerującej, że
to klasa aClass a nie zmienna. Funkcja anonimowa zwraca natomiast
deklarację tak samo nazwanej klasy: czyli aClass.
Super, co?
--
Pozdrawiam,
Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Borys Pogoreło
Date: Sat, 27 Jan 2018 21:59
Date: Sat, 27 Jan 2018 21:59
19 lines
1530 bytes
1530 bytes
Dnia Thu, 25 Jan 2018 20:19:34 +0100, Marek S napisał(a): > 1. Wprowadzono wreszcie pojęcie klas i dziedziczenia ale... zignorowano > zmienne prywatne. Nie ma czegoś takiego w samych założeniach. Bo te klasy i dziedziczenie to tylko opakowanie do dziedziczenia prototypowego i kopozycji. Ono jest na tyle nietypowe, że zdecydowano się na takie uproszczenia. A Ty próbujesz podejść JS od strony klas. > Czy też sądzicie, że zmienne prywatne to przeżytek? Nie. Ale próbujesz, jak to angole mawiają, porównywać pomarańcze do jabłek. Zmienne prywatne możesz zasymulować funkcją zwracającą obiekt. Będzie on nadal mieć dostęp do kontekstu funkcji. -- Borys Pogoreło borys(#)leszno,edu,pl
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Sun, 28 Jan 2018 14:07
Date: Sun, 28 Jan 2018 14:07
48 lines
3250 bytes
3250 bytes
W dniu 27-01-2018 o 22:59, Borys Pogoreło pisze: >> 1. Wprowadzono wreszcie pojęcie klas i dziedziczenia ale... zignorowano >> zmienne prywatne. Nie ma czegoś takiego w samych założeniach. > > Bo te klasy i dziedziczenie to tylko opakowanie do dziedziczenia > prototypowego i kopozycji. Ono jest na tyle nietypowe, że zdecydowano się > na takie uproszczenia. A Ty próbujesz podejść JS od strony klas. W JS istnieje wyrażenie class, które zachowuje się odmiennie niż dotychczasowe symulowanie klas za pomocą funkcji. Potrafi dziedziczyć po innej klasie za pomocą extends w fazie deklaracji (to już wykracza poza model kompozycji), posiada operator "super" umożliwiający tworzenie odwołań do metod klasy, w przeciwieństwie to funkcji nie obowiązuje hoisting, kod klasy zawsze uruchamiany jest w trybie ścisłym, metody klasy nie podlegają wyliczeniu, metody klasy nie mają - w odróżnieniu od funkcji ich udających - konstruktorów, nie da się wywołać konstruktora klasy inaczej niż poprzez new. Wszystko wskazuje na to, że klasa w JS zbliża się powoli do ich odpowiedników znanych w innych językach. Tak, wiem, dziedziczenie jest nadal prototypowe, co implikuje ograniczenia. Przypuszczam, że w ES8,9,100 w końcu keyword "private" również zostanie wykorzystany, choć z protected pewnie problem zawsze będzie. Dlaczego zatem podejście do klas w JS jako do prawdziwych klas jest niewłaściwe? >> Czy też sądzicie, że zmienne prywatne to przeżytek? > > Nie. Ale próbujesz, jak to angole mawiają, porównywać pomarańcze do jabłek. > > Zmienne prywatne możesz zasymulować funkcją zwracającą obiekt. Będzie on > nadal mieć dostęp do kontekstu funkcji. Sęk w tym, że ja nie chcę postępować rodem z ES5 skoro mamy epokę ES6 a niebawem ES7. Romanowi pokazałem kod jakiego używam do symulowania zmiennych prywatnych korzystając z mechanizmów ES6. Nie chcę go dublować w tym wątku - zerknij proszę na moją odpowiedź z 27.01 jemu udzieloną. Niestety... bez enkapsulacji nadal nie da się obejść problemu. Przynajmniej do czasu kiedy moduły nie zaczną w przeglądarkach działać. Natomiast to co się udało wyeliminować, to zwracanie obiektu przez funkcję. -- Pozdrawiam, Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Wojciech Bancer
Date: Sun, 28 Jan 2018 15:14
Date: Sun, 28 Jan 2018 15:14
61 lines
3209 bytes
3209 bytes
On 2018-01-28, Marek S <precz@spamowi.com> wrote:
> W dniu 27-01-2018 o 22:59, Borys Pogoreło pisze:
>
>>> 1. Wprowadzono wreszcie pojęcie klas i dziedziczenia ale... zignorowano
>>> zmienne prywatne. Nie ma czegoś takiego w samych założeniach.
>>
>> Bo te klasy i dziedziczenie to tylko opakowanie do dziedziczenia
>> prototypowego i kopozycji. Ono jest na tyle nietypowe, że zdecydowano się
>> na takie uproszczenia. A Ty próbujesz podejść JS od strony klas.
>
> W JS istnieje wyrażenie class, które zachowuje się odmiennie niż
> dotychczasowe symulowanie klas za pomocą funkcji.
Nie zachowuje się. To tylko tzw. syntax sugar.
Wszystkie te rzeczy można osiągnąć w ES5, zresztą bez tego nie działałyby
transpilery w rodzaju TypeScript, czy Babela.
> Potrafi dziedziczyć po innej klasie za pomocą extends w fazie deklaracji
> (to już wykracza poza model kompozycji), posiada operator "super" umożliwiający
> tworzenie odwołań do metod klasy, w przeciwieństwie to funkcji nie obowiązuje
> hoisting, kod klasy zawsze uruchamiany jest w trybie ścisłym, metody
> klasy nie podlegają wyliczeniu, metody klasy nie mają - w odróżnieniu od
> funkcji ich udających - konstruktorów, nie da się wywołać konstruktora
> klasy inaczej niż poprzez new.
To co robi "extends", to mniej więcej to co poniżej, tylko w przyjemniejszej
składni.
----
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?', rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
----
--
Wojciech Bańcer
wojciech.bancer@gmail.com
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Sun, 28 Jan 2018 19:35
Date: Sun, 28 Jan 2018 19:35
37 lines
2658 bytes
2658 bytes
W dniu 28-01-2018 o 16:14, Wojciech Bancer pisze: > Nie zachowuje się. To tylko tzw. syntax sugar. Ok, skąd czerpiesz tą wiedzę? Gdy pokaże się nowa wersja standardu "czegoś": CSS, JS, PHP, HTML to zawsze zabieram się do analizowania "what's new", zapoznaję się z W3C, kupuję w razie potrzeby podręczniki zawierające kompendium zmian etc. Sporadycznie spotykam się ze stwierdzeniem, że to tylko syntax sugar, jak się wyraziłeś, zamiast rewolucji. Przykładowo w podręczniku "ECMASCRIPT 6 - przewodnik po nowym standardzie JS" w rozdziale 9 piszą raczej jednoznacznie iż tworzenie klas w ES6 to nowość zrywająca z podejściem w ES5, gdzie napisano: "...ECMAScript 5 wiele bibliotek dostarczało narzędzia, dzięki którym mogło się wydawać, że JavaScript obsługuje klasy. Wprawdzie pewna część programistów była mocno przekonana, że język nie potrzebuje klas, ale ilość utworzonych bibliotek przeznaczonych do obsługi klas spowodowała dołączenie klas w specyfikacji ECMAScript 6." Skąd zatem takie wypowiedzi? Autor książki nie ma bladego pojęcia o świecie więc sobie coś palnął ot tak? > To co robi "extends", to mniej więcej to co poniżej, tylko w przyjemniejszej > składni. > (...) // subclass extends superclass > Rectangle.prototype = Object.create(Shape.prototype); > Rectangle.prototype.constructor = Rectangle; Ponoć właśnie nie do końca. Funkcjonalnie w ES5 owszem. Ale w ES6 i w klasach nie da się tego przeprowadzić bo prototype klas jest read only. Ponoć w tym kierunku będzie rozwój JS prowadzony. -- Pozdrawiam, Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Wojciech Bancer
Date: Sun, 28 Jan 2018 21:01
Date: Sun, 28 Jan 2018 21:01
57 lines
3248 bytes
3248 bytes
On 2018-01-28, Marek S <precz@spamowi.com> wrote: [...] >> Nie zachowuje się. To tylko tzw. syntax sugar. > > Ok, skąd czerpiesz tą wiedzę? Z internetu i przemyśleń własnych :) Np. z MDNa. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical- sugar over JavaScript's existing prototype-based inheritance. The class syntax- does not introduce a new object-oriented inheritance model to JavaScript." Czy: https://stackoverflow.com/questions/36419713/are-es6-classes-just-syntactic-sugar-for-the-prototypal-pattern-in-javascript/36419728 oraz z faktu, że nie mamy pojęcia klasy per se, tylko wszystko jest nadal oparte o prototypy. [...] > "...ECMAScript 5 wiele bibliotek dostarczało > narzędzia, dzięki którym mogło się wydawać, że JavaScript obsługuje > klasy." Wydawać? Obsługuje, po prostu w inny sposób (prototype inheritance vs class inheritance), np: https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9 > Wprawdzie pewna część programistów była mocno przekonana, że > język nie potrzebuje klas, ale ilość utworzonych bibliotek > przeznaczonych do obsługi klas spowodowała dołączenie klas w > specyfikacji ECMAScript 6." Czyli dodali syntax sugar. > Skąd zatem takie wypowiedzi? Autor książki nie ma bladego pojęcia o > świecie więc sobie coś palnął ot tak? Czemu mnie pytasz? >> Rectangle.prototype.constructor = Rectangle; > > Ponoć właśnie nie do końca. Funkcjonalnie w ES5 owszem. Ale w ES6 i w > klasach nie da się tego przeprowadzić bo prototype klas jest read only. > Ponoć w tym kierunku będzie rozwój JS prowadzony. Czego się nie da przeprowadzić? Wykonać kodu powyżej np. na node 8? Da się. Nie da się wywołać konstruktora "klasy" jak zauwazyłeś, ale to nadal jest jedynie syntax sugar. -- Wojciech Bańcer wojciech.bancer@gmail.com
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Marek S
Date: Mon, 29 Jan 2018 18:01
Date: Mon, 29 Jan 2018 18:01
49 lines
2780 bytes
2780 bytes
W dniu 28-01-2018 o 22:01, Wojciech Bancer pisze:
>> "...ECMAScript 5 wiele bibliotek dostarczało
>> narzędzia, dzięki którym mogło się wydawać, że JavaScript obsługuje
>> klasy."
>
> Wydawać?
No więc ja też z internetu, a konkretnie w tym przypadku - wspomnianej
książki tą wiedzę czerpię. Jeśli autor zdanie tak sformułował, to ulegam
przeświadczeniu, że teraz jest inaczej, lepiej. Nie potrafię więc
zadecydować, które ze sprzecznych (ogólnie teraz mówię, bez nawiązania
do klas) oficjalnie publikowanych informacji przez wydawnictwa jest
prawdą, a która fałszem.
>>> Rectangle.prototype.constructor = Rectangle;
>>
>> Ponoć właśnie nie do końca. Funkcjonalnie w ES5 owszem. Ale w ES6 i w
>> klasach nie da się tego przeprowadzić bo prototype klas jest read only.
>> Ponoć w tym kierunku będzie rozwój JS prowadzony.
>
> Czego się nie da przeprowadzić?
Modyfikowania prototypu klasy w odróżnieniu od prototypu funkcji.
> Wykonać kodu powyżej np. na node 8?
> Da się. Nie da się wywołać konstruktora "klasy" jak zauwazyłeś, ale
> to nadal jest jedynie syntax sugar.
Strasznie to mętne. "Syntax sugar" tłumaczę sobie jako skrócony zapis
czego, co przedtem było rozwlekłe.
x=> x+1
zamiast
function cosTam(x) {return x+1;}
Albo Object.assign() zamiast funkcji typu mix-in
Tymczasem jeśli coś zachowuje się inaczej, tak jak np prototypy klas z
ES6 względem prototypów funkcji z ES5 albo możliwość odwoływania się do
metod klasy bazowej poprzez "super", to jaki tu cukierek? To nowy
mechanizm. Tego nie da się zasymulować w ES5.
--
Pozdrawiam,
Marek
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Wojciech Bancer
Date: Mon, 29 Jan 2018 19:12
Date: Mon, 29 Jan 2018 19:12
19 lines
1789 bytes
1789 bytes
On 2018-01-29, Marek S <precz@spamowi.com> wrote: > Tymczasem jeśli coś zachowuje się inaczej, tak jak np prototypy klas z > ES6 względem prototypów funkcji z ES5 albo możliwość odwoływania się do > metod klasy bazowej poprzez "super", to jaki tu cukierek? To nowy > mechanizm. Tego nie da się zasymulować w ES5. Przecież Ci podałem kod który stanowi odwzorowanie "super". "Klasa.call(this, 'argument');" ew. "Klasa.prototype.metoda.call(this)" Da się, tylko syntax jest bardziej paskudny. https://github.com/addyosmani/es6-equivalents-in-es5#classes Jakby się czegoś nie dało, to wg Ciebie na jakiej zasadzie działałby Babel? -- Wojciech Bańcer wojciech.bancer@gmail.com
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Borys Pogoreło
Date: Tue, 30 Jan 2018 19:36
Date: Tue, 30 Jan 2018 19:36
19 lines
1474 bytes
1474 bytes
Dnia Mon, 29 Jan 2018 19:01:56 +0100, Marek S napisał(a):
> Strasznie to mętne. "Syntax sugar" tłumaczę sobie jako skrócony zapis
> czego, co przedtem było rozwlekłe.
>
> x=> x+1
>
> zamiast
>
> function cosTam(x) {return x+1;}
Arrow functions nie są skróconym zapisem, działają nieco inaczej - nie
zmieniają kontekstu.
"Syntax sugar" to np. skrócony sposób tworzenia tablicy.
--
Borys Pogoreło
borys(#)leszno,edu,pl
Re: Nikomu niepotrzebne zmienne prywatne?
Author: Wojciech Bancer
Date: Thu, 01 Feb 2018 21:15
Date: Thu, 01 Feb 2018 21:15
15 lines
1621 bytes
1621 bytes
On 2018-01-30, Borys Pogoreło <borys@pl.edu.leszno> wrote:
>> zamiast
>>
>> function cosTam(x) {return x+1;}
>
> Arrow functions nie są skróconym zapisem, działają nieco inaczej - nie
> zmieniają kontekstu.
Co jest skróconym zapisem mniej więcej takiej postaci:
function (x) {return x+1;}.bind(this);
--
Wojciech Bańcer
wojciech.bancer@gmail.com
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads