Софтуерно Инженерство
Loading...
+ Нов въпрос
GrozdanAndonov avatar GrozdanAndonov 1 Точки

javascript ES6 class with getters only

Здравейте, искам да попитам защо ми дава грешка, че полетата са "Read only" , когато пиша само getter-и без setter-и в клас на ES6?

Това ми е кода:

class BasePunchStarter {

    constructor(id,name,manufacturer,description,genres,targetPrice){
        if(new.target==BasePunchStarter){
            throw new TypeError("BasePunchStarter class cannot be instantiated directly!");
        }
        if(typeof id =="number") {
            //noinspection JSUnresolvedVariable
            this.id = id;
        }else throw new TypeError("ID must be a number!");
        if(typeof name=="string") {
            //noinspection JSUnresolvedVariable
            this.name = name;
        }else throw new TypeError("Name must be a string!");
        if(typeof manufacturer=="string") {
            //noinspection JSUnresolvedVariable
            this.manufacturer = manufacturer;
        }else throw new TypeError("Manufacturer must be a string!");
        if(typeof description=="string") {
            //noinspection JSUnresolvedVariable
            this.description = description;
        }else throw new TypeError("Description must be a string!");
        if(typeof genres=="Object"){
            //noinspection JSUnresolvedVariable
            this.genres=genres;
        }else new TypeError("Genres must be an Array of strings!");
        if(typeof targetPrice=="number") {
            //noinspection JSUnresolvedVariable
            this.targetPrice = targetPrice;
        }else new TypeError("Target price must be a number!");
        this.accumulatedMoney=0;
    }
    get accumulatedMoney(){
        return this._accumulatedMoney;
    }
    set accumulatedMoney(money){
        this._accumulatedMoney=money;
    }
    get id(){
        return this._id;
    }
    get name(){
        return this._name;
    }
    get manufacturer(){
        return this._manufacturer;
    }
    get description(){
        return this._description;
    }
    get genres(){
        return this._genres;
    }
    get targetPrice(){
        return this._targetPrice;
    }
}

module.exports = BasePunchStarter;
Използвам "//noinspection JSUnresolvedVariable" за да не ми пищи за грешката и няма проблем, но едва ли е най-добрият вариянт за справяне с проблема.
0
JavaScript Advanced
Silvave avatar Silvave 127 Точки
Best Answer

Здрасти, гърми ти, защото с get-ъра може само да достъпваш, но не и да им задаваш стойности, както правиш ти в constructor-a. Затова ти дава, че тези полета са "Read only". А от друга страна "private" пропъртитата ти, които достъпваш с гетърите не са ти сетнати и ще връщат "undefined". Решението ти е или да сетваш "private" пропъртитата в constructor-a и да ги достъпваш през get-ърите...

constructor(id, ...){
if(typeof id =="number") {
   //noinspection JSUnresolvedVariable
   this._id = id;
}
get id(){
   return this._id;
}

или да направиш и отделен set-ър за всеки твой get-ър, който да ти set-ва "private" пропъртито...

constructor(id, ...){
if(typeof id =="number") {
   //noinspection JSUnresolvedVariable
   this.id = id;
}
get id(){
   return this._id;
}
set id(newId){
   return this._id = newId;
}

 

0
18/02/2017 00:23:25
GrozdanAndonov avatar GrozdanAndonov 1 Точки

Супер сиии!!! Мерси много!!! yes laugh

1
Nikola_Andreev avatar Nikola_Andreev 671 Точки

Не би трябвало да ти пищи, при мен се компилира твоя код. С версия на WebStorm 2016 2.2 съм, последната е 3.3 до колкото знам но едва ли е от това.

0
GrozdanAndonov avatar GrozdanAndonov 1 Точки

Аз съм с последната.Много странно!!!

Благодаря все пак! ;)

0
17/02/2017 23:51:39
CvetanPetkov avatar CvetanPetkov 55 Точки

А защо си правил гетъри, при положение, че можеш да си достъпваш пропъртитата директно. Нали сетери и гетери се слагат, за да имаме private на пропъртитата. А освен това сетърите са нужни в твоя случай поне за проверките, които правиш. Имаш един сетър, който май никой не го вика от конструктора понеже си му забил нула, мисля си че си искал да сетваш acumulatedMoney отвън, но това се прави с функция - сетър не можеш да извикаш ръчно. 

0
GrozdanAndonov avatar GrozdanAndonov 1 Точки

Условието на задачата е :

Implement the BasePunchStarter class, so that it is initialized with the following parameters:

  • id – a Number
  • name – a String
  • manufacturer – a String
  • description – a String
  • genres – an Array of Strings
  • targetPrice – a Number

The class should only hold getters for those properties, no setters! Make sure each parameter is of the right type, otherwise throw a TypeError.

The class also has another property, which is private, but has getter and setter. The property is accumulatedMoney. It’s initial value is 0. It is a NUMBER.

Make sure the base class cannot be instantiated directly. Throw an Error if such an attempt is made.

Как предлагаш да стане?

0
18/02/2017 03:13:25
CvetanPetkov avatar CvetanPetkov 55 Точки

Constructor (args...) {

   This.accumulatedMoney = 0;

}

Set accumulatedMoney() {

   This._accumulatedMoney = 0;

}

Get accumulatedMoney() {

   Return this._accumulatedMoney

}

UpdateAccumulatedMoney(newMoney) {

   This._accumulatedMoney += newMoney;

}

Така реално имаш 2 променливи accumulatedMoney. И когато кажеш BasePunchStarter.accumulatedMoney - ще вземеш стойността от гетера с променливата _accumulatedMoney, която е извън конструктора, каквато е и целта на тези private променливи. Пазят конструктора от злонамерен и директен достъп. Малко е тъпо ООП-то в javaScript, цяла вечер се мъчех и аз с един метод в един клас.

Накрая имаш и едон метод, който достъпваш с BasePunchStarter.updateAccumulatedMoney(newMoney);

И така променяш стойността на _accumulatedMoney. Не можеш да направиш ъова през сетъра, той се изпълнява само веднъж при инстанцирането на класа.

0
18/02/2017 03:42:02