使用getter定义工厂函数中的只读属性

时间:2018-12-12 13:38:34

标签: javascript ecmascript-6 ecmascript-5

因此,似乎有两种在JS中定义只读属性的可行方法-使用 Object.defineProperty getter

就我而言,我必须坚持使用吸气剂方法,但考虑到上下文,这似乎不太合适,因为我是在 LoyaltyCard 工厂功能内实现吸气剂的

属性“ id”,“ balance”和“ discount”必须定义为只读。从'id'开始,存在语法错误,返回:“ 意外令牌,应为; ”。

是否有一种如https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get中所建议的那样巧妙地实现getter的方法,或者我可能遗漏了一些东西?

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 :(得分:0)

请考虑使用“模块模式”将要存储的数据封装为“私有”。这里的演示

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