【发布时间】:2018-12-12 13:38:34
【问题描述】:
看来,在 JS 中定义只读属性有两种可行的方法 - 使用 Object.defineProperty 或 getter。
就我而言,我必须坚持使用 getter 方法,但考虑到上下文,它似乎并不合适,因为我正在 LoyaltyCard 工厂函数中实现 getter .
必须将属性“id”、“balance”和“discount”定义为只读。从'id'开始,出现语法错误,返回:“Unexpected token, expected ;”。
有没有办法巧妙地实现 getter,如 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();
【问题讨论】:
-
无论如何你都不希望 getter 被这样定义,因为每次访问属性时你都会得到一个新的随机 id。
-
你为什么不想使用
defineProperty? -
不是我反对 difineProperty,而是使用 getter 将某些属性定义为只读的给定任务(大概是因为它是一种更现代的方法)
-
只使用 getter 不会使属性只读。如果您直接分配该属性,它将优先于 getter
-
如果它正是我需要的,但只是在某个执行点上呢?二传手进入游戏?
标签: javascript ecmascript-6 ecmascript-5