WebHU - Programozási kérdések és válaszok

Hozzáférés az alaposztály védett mezőihez származtatottból (ES2019 privát osztály)

Szeretnék hozzáférni az alaposztály privát mezőihez a származtatott osztályokból anélkül, hogy nyilvánossá tenném őket (amit más nyelvekben „védettnek” neveznek).

Vegye figyelembe a következő osztályt:

class Animal {

  #privateProp;

  constructor() {

  this.#privateProp = 12;

  }
}

Most a bővítő osztály:

class Cat extends Animal {

  constructor() {

    super();
  }

  doIt() {

    console.log(this.#privateProp) // 1 below
    console.log(super.#privateProp) // 2 below
  }
}

Úgy szeretném végrehajtani, mintha védett lenne:

new Cat().doIt();

De megkapja (illetve):

  1. Nem elkapott szintaxishiba: A „#privateProp” privát mezőt egy bezáró osztályban kell deklarálni
  2. Uncaught Syntax Error: Váratlan privát mező

Figyeljük meg, hogy ez a kód tökéletesen működne, amikor a privateProp nyilvánossá válik, de szeretnék elérni egy védett viselkedést, és hozzáférést szeretnék elérni a „privát” mezőkhöz, mint bármely nyelv, amely támogatja az öröklődést.

Minden segítséget nagyra értékelünk.


  • Hm .. a privát valójában privátnak kell lennie, tehát nincs hozzáférés az osztályon kívül. 15.04.2020
  • a privát mezők valamiért privátak :) 15.04.2020
  • Rendben, elnézést, hadd változtassam "védett"-re 15.04.2020
  • Tekintse meg ezt a stackoverflow jobb megértéséhez. com/questions/34517581/ 15.04.2020
  • Tehát miután elolvastam, azt hiszem, még nincs egyszerű módja ennek a viselkedésnek a JS-ben való elérésére. 15.04.2020

Válaszok:


1

korlátozott hozzáférésű getter és setter metódusokkal hozhat létre privát tulajdont, ha ellenőrzi, hogy a konstruktor nem a szülőosztályhoz tartozik-e.

class Animal {
  #privateProp = 12;
  set Prop(val) {
    if (this.constructor.name !== 'Animal')
      return this.#privateProp = val;
    throw new Error('Cannot Access Protected property');
  }
  get Prop() {
    if (this.constructor.name !== 'Animal')
      return this.#privateProp;
    throw new Error('Cannot Access Protected property');
  }
}

class Cat extends Animal {
  get Prop() {
    return super.Prop;
  }

  set Prop(val) {
    super.Prop = val
  }
}

let cat = new Cat();
console.log(cat.Prop)
cat.Prop = 22
console.log(cat.Prop)

console.log(new Animal().Prop);

15.04.2020
  • Gyönyörű! Köszönöm 16.04.2020
  • Ez már nem magántulajdon (vagy védett), ha nyilvános gettereket és settereket biztosít. 20.07.2020
  • @Bergi ők nem a védett változók, hanem egy megkerülő megoldás ennek elérésére, itt csak a szülő vagy a gyermek osztályok férhetnek hozzá a változókhoz, nem bármely más osztály, amely valójában védett változó viselkedés. Ha más osztályokban is hozzá kell férnünk ezekhez a változókhoz, akkor egy másik getter és setters wrappert is megvalósíthatunk a szülő osztályban. 22.07.2020
  • @AZ_ Nem. Mindenki elérheti ezeket a tulajdonságokat az alosztálypéldányokon bárhonnan, amint azt a kódja (console.log(cat.Prop); cat.Prop = 22) mutatja. Nem korlátozódik a gyermekosztályokon belüli kódra. 22.07.2020
  • @Bergi így nem a szülő Prop védett tulajdonához férsz hozzá, hanem a gyerek Prop köztulajdonához. Csak úgy megtartottam, ahogy a szülőben volt. A gyermekben az OP dönthet úgy, hogy a getter és a setter ne adja vissza pontosan a szülő kelléket. ez lehet return super.Prop+1; vagy esetleg csak módszerben használjuk. 22.07.2020
  • @AZ_ Ha a gyerek nem írná felül, akkor is elérhetőek lennének az örökölt getterek/setterek. És még ha felül is írták őket, használhatjuk a szülőtől származó gettereket/settereket a gyermekpéldányon (pl. Reflect.get(Animal.prototype, "Prop", cat) esetén) 22.07.2020
  • ahh értem. @Bergi 22.07.2020

  • 2

    A mezők a változók blokk-hatóköréhez hasonló módon privátak; ha egy tulajdonság privát egy bizonyos class számára, akkor csak az adott osztályon belül lehet rá hivatkozni. Ha kiterjeszti az osztályt, az nem lesz látható a származtatott osztályban.

    Készíthetsz gettert/settert a szuperosztályon, ha szeretnél vele dolgokat csinálni az alosztályból:

    class Animal {
      #privateProp = 12;
      setProp(val) {
        this.#privateProp = val;
      }
      getProp() {
        return this.#privateProp;
      }
    }
    class Cat extends Animal {
      doIt() {
        console.log(this.getProp());
      }
    }
    new Cat().doIt();

    Egy másik módszer az, hogy a "privát" mezőt csak az osztálydeklarációkra ható WeakMap-ként határozza meg:

    const { Animal, Cat } = (() => {
      const privateProps = new WeakMap();
      class Animal {
        constructor() {
          privateProps.set(this, 12);
        }
      }
      class Cat extends Animal {
        doIt() {
          console.log(privateProps.get(this));
        }
      }
      return { Animal, Cat };
    })();
    new Cat().doIt();

    15.04.2020
  • tényleges getter és setter metódusokat is létrehozhat, pl. get privateProp(){} 15.04.2020
  • Nem ettől lett a #privateProp ténylegesen nyilvános? így bárki mehet új Animal().getProp() -ba? 15.04.2020
  • @TamirNakar Az egyetlen módja annak, hogy egy alosztály kölcsönhatásba lépjen egy szuperosztály privát mezőjével, az az, hogy a szuperosztály olyan funkciókat tesz elérhetővé, amelyek valamilyen módon lehetővé teszik az interakciót. 15.04.2020
  • @CertainPerformance, egyetértünk. De a lehető legkevesebb interakciót szeretném engedélyezni. A java for instane-ban a mezőt védettként határozza meg, és csak a származtatott osztályok férhetnek hozzá ehhez a kellékhez. Elérhető ez a viselkedés? 15.04.2020
  • @TamirNakar A jelenlegi szintaktikai szabályokkal sajnos nem igazán. Ha én lennék, ebben a helyzetben egy WeakMap-et készítenék, amely csak az osztályokra vonatkozik 15.04.2020
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..