Определение свойств только для чтения внутри фабричной функции с использованием геттеров - PullRequest
0 голосов
/ 12 декабря 2018

Итак, похоже, есть два рабочих подхода к определению свойств только для чтения в JS - с Object.defineProperty или getter .

В моемВ этом случае я должен придерживаться метода получения, но с учетом контекста он не совсем подходит, так как я реализую метод получения в пределах фабричной функции LoyaltyCard .

Свойства 'id', 'balance' и 'discount' должны быть доступны только для чтения.Начиная с 'id', возникает синтаксическая ошибка, возвращающая: " Неожиданный токен, ожидается; ".

Есть ли способ аккуратно реализовать метод получения, как это предлагается в:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get или, может быть, я что-то упустил?

function rand(min, max) {
  return Math.ceil((max - min + 1) * Math.random()) + min - 1;
}

function generateId() {
  return Array(4).fill(1).map(value => rand(1000, 9999)).join('-');
}  


let LoyaltyCard = function(name, sum) {
  this.owner = name;
  this.id; //unfinished
  this.balance = sum; 
  this.discount = 0; 
  this.orders = Array.of(sum);
}

LoyaltyCard.prototype.getFinalSum = function(sum) {
  let calculatedDiscount;

  if (this.balance >= 3000 && this.balance < 5000) {
    calculatedDiscount = 3;
  } else if (this.balance >= 5000 && this.balance < 10000){
    calculatedDiscount = 5;
  } else if (this.balance >= 10000) {
    calculatedDiscount = 7; 
  }

  Object.defineProperty(this, 'discount', {
    value: calculatedDiscount
  });

  finalSum = sum * (1 - this.discount / 100);
  this.orders.push(sum);
  return finalSum;
}

LoyaltyCard.prototype.append = function(sum) {
  this.orders.push(sum);
  return Object.defineProperty(this, 'balance', {
    value: this.balance += sum
  });
}

LoyaltyCard.prototype.show = function() {
  console.log(`Card ${this.id}:\nOwner: ${this.owner}\nBalance: ${this.balance} Q\nCurrent discount: ${this.discount} %\nOrders:\n  #1 on ${this.orders[0]} Q\n  #2 on ${this.orders[1]} Q`);
}

//Call sample:

const card = new LoyaltyCard('John Doe', 6300);

let newOrderSum = 7000;
let finalSum = card.getFinalSum(newOrderSum);
console.log(`The final order amount for the order on ${newOrderSum} Q using the loyalty card will be 
${finalSum} Q. ${card.discount} %. discount applied`);

card.append(newOrderSum);
console.log(`Loyalty card balance after the purchase ${card.balance} Q.`);
card.show();

1 Ответ

0 голосов
/ 20 декабря 2018

Пожалуйста, рассмотрите "шаблон модуля", чтобы инкапсулировать данные, которые вы хотите сохранить, как "частные".Здесь демо

function LoyaltyCard(name, sum) {
  let owner = name;
  let id; // get id from your generateId()
  let balance = sum;
  let discount = 0;
  let orders = Array.of(sum);

  function getFinalSum(sum) {
    /* implementation */
    balance += sum; // DEMO ONLY
    return sum; //  DEMO ONLY
  }

  function append(sum) { /* implementation */ }

  function show() { /* implementation */ }

  return {
    get name() {
      return owner;
    },
    set name(name) {
      owner = name;
    },
    get balance() {
      return balance;
    },
    getFinalSum,
    append,
  };
}

const card = LoyaltyCard('peter', 100);
console.log(card.balance); // 100
console.log(card.getFinalSum(200)); // 200
console.log(card.balance); // 300
card.balance = 50; // silently fail
console.log(card.balance); // 300

Для получения дополнительной информации о «шаблоне модуля», пожалуйста, прочитайте YDKJS https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch5.md

...