[英]Are `getter` and `setter` necessary in JavaScript?
class Employee {
constructor(name, age) {
this._name = name;
this.age = age;
}
doWork() {
return `${this._name} is working`;
}
get name() {
return this._name.toUpperCase();
}
set name(newName){
if(newName){
this._name = newName;
}
}
}
let man = new Employee('A', 10);
console.log(man.name, man.age);
man.name = 'B';
man.age = 20;
console.log(man.name, man.age);
這是我的代碼。 我為_name
成員創建了一個getter
和setter
。 我沒有為age
創建getter
和setter
。
但是兩者都可以像這樣更新這兩個字段man.name = 'B';man.age = 20;
所以我很困惑,JavaScript 中是否需要getter
和setter
?
是的,getter或setter有時非常有用,但只需要在需要特定功能時使用它們 - 否則沒有getter或setter的普通屬性訪問就可以了。
如果要在每次請求屬性時運行某些代碼,則可以使用getter。 在您的示例中,無論名稱是什么,getter始終返回名稱的大寫版本,同時保留實際案例以供內部使用。
如果要在每次設置屬性時運行某些代碼,則可以使用setter。 在您的情況下,它會阻止設置假名稱。 沒有getter / setter,您無法實現這些功能。
當您不需要getter或setter特殊邏輯時,直接屬性訪問是一種非常好的方法。
getter和setter也可能獲取並設置一些不公開的屬性(因此通過正常的屬性訪問根本不可用),因為它存儲在某個地方(不是作為此對象的屬性)或私有存儲或即使它存儲在其他地方,例如某些硬件設備中。 在這些情況下,getter和setter會模擬實際不存在的屬性值。 因此,它們簡化了界面,同時允許從任何地方存儲或檢索實際值。
必要? 沒有。
是否有最佳表達為getter / setter的場景? 是。 考慮“計算屬性”:
//declare an object
rectangle = {
x: 10,
y: 20,
get area() { return this.x * this.y } //won't occupy storage
}
//usage
log('the area is', rectangle.area) //=> 'the area is 200'.
// cleaner syntax (no parentheses)
考慮API設計人員的需求 - 他們很可能對用戶如何看待他們的API過於敏感。 每一位(或在這種情況下,括號)都計入清理界面。
是的,他們是非常必要的。 只是不是每個財產。
以下是設置者的兩個理由:
假設您的值必須是0到100之間的整數。您的setter可以驗證傳入值的類型是否正確並且在正確的范圍內:
class Range { set value(newVal) { let val = Number(newVal); if( newVal == null || typeof newVal === 'string' || !Number.isInteger(val) || val < 0 || val > 100 ) { const err = `'value' must be an integer from 0 to 100 and not ${newVal}`; console.error(err); //throw new TypeError(err); } // save newVal } } const x = new Range(); x.value = 200; x.value = 10; x.value = "10"; x.value = new Number(22);
class ValOutput { constructor(el) { this._el = el; } set value(newVal) { this._el.innerHTML = `The value is ${newVal}`; } } const output = document.getElementById('output'); const x = new ValOutput(output); x.value = 100; setTimeout(() => { x.value="after timeout"; }, 2000);
<div id="output"></div>
以下是吸氣劑的兩個原因:
class Rect { constructor(l = 0,t = 0,r = 0,b = 0) { this.left = l; this.top = t; this.right = r; this.bottom = b; } get height() { return this.bottom - this.top; } get width() { return this.right - this.left; } } let a = new Rect(0, 10, 33, 55); console.log(a.width, a.height); a = new Rect(35, 50, 200, 200); console.log(a.width, a.height);
class OtherThing { constructor(a) { this.a = a; } } class MyObj { constructor(oVal = 0) { this._otherThing = new OtherThing(oVal); } get a() { return this._otherThing.a; } } const x = new MyObj(); console.log(xa); const y = new MyObj('tacos'); console.log(ya);
getters
和setter
是隱藏私人數據的好方法。 是的,我知道ES規范引入了私有變量,但這里有一個例子,直到該規范是標准的。
const privateVars = new WeakMap(); class MyObj { constructor(inVal) { const pVars = { age: inVal, dog: '' } privateVars.set(this, pVars); } get dog() { return privateVars.get(this).dog; } set dog(newVal) { privateVars.get(this).dog = newVal; } } const x = new MyObj(10); const y = new MyObj(20); x.dog = "woof"; y.dog = "bark"; console.log(x.dog); console.log(y.dog);
你需要getter
和setters
嗎? 不,他們有必要嗎? 是。
Getter和setter用於訪問PRIVATE PROPERTY或從外部修改它。 GETTER是一個用於讀取屬性的函數。如果你想從外部設置私有屬性的值,我們定義一個SETTER函數。 這是一個例子:
function Circle(radius){
this.radius=radius;
let originPoint={x:0,y:0}; //originPoint is a private property.
this.area=function(){console.log("area")};
Object.defineProperty(this,originPoint,{
get:function(){
return originPoint;
};
set:function(value){
originPoint=value;}
}
}
const circle=new Circle(10);
circle.originPoint //will call "get" function
circle.originPoint={x:2,y:3}
實現getter和setter功能的一個主要原因是關閉一個功能差距,需要人們破解js解釋器/瀏覽器以實現瀏覽器可以執行的一項功能:
element.innerHTML = "<div> some HTML string </dif>";
現在, innerHTML
可能看起來像一個屬性,但它實際上更像是一個函數。 它實際上是一個HTML編譯器。
你可以通過嘗試做到這一點:
element.innerHTML += "<table>";
element.innerHTML += "<tr><td>test</td></tr>"; // does not work
這是因為對innerHTML
的第一次“調用”將html編譯為:
<table></table>
第二行將失敗,因為表外的<tr>
是無效的HTML。
使用getter和setter,你最終可以在純javascript中實現這樣的功能 - 使屬性訪問觸發函數調用。
當然, innerHTML
只是getter和setter的一個例子,也是API的一個非常糟糕的例子。 這取決於你的創造力,你可以用吸氣劑和制定者實際做什么。
現在,根據我個人的意見(這只是我的觀點,所以把它當作它的價值):我認為innerHTML
提供了一個很好的例子,說明為什么通常不應該使用getter和setter。 對<table>
的困惑是打破用戶期望的一個很好的例子。 如果innerHTML
被實現為element.appendHTML()
那么它的行為就不那么令人驚訝了。 作為程序員,如果屬性訪問做了我不期望的事情,我會感到非常驚訝。
也就是說,我很高興存在getter和setter,使語言庫功能可以自行實現,而無需訴諸於C / C ++中的黑客攻擊。
使用getter
和setter
方法取決於你在類中的屬性,如果你想使一個屬性只是只讀它的真實使用getter
方法如下:
function Person(name, age){ var _name = name; this.age = age; this.getName = function(){ return _name; } } var teacher = new Person('Sara', 24); //now you can just get the name of teacher alert(teacher.getName());
我們使用該類的原因是保存單個實體的所有屬性。但是您可以通過創建對象來完成,並且可以在需要時將屬性附加到該對象。
當代碼變大時,您無法調試代碼失敗的位置。如果您遵循結構,您可以輕松地dubug.Because因為每個實體將在單獨的文件中,邏輯將是分開的。
但是JavaScript是一種面向對象的編程語言。我們之所以使用類而不是對象,這對於getter和setter來說是一樣的。它不像你可以在哪里使用你不需要的地方。這是一個很好的做法來設置和獲取所有屬性通過setter和getters。
在某個時間點之后,您可能會在設置屬性時添加一些條件,例如,如果一個人的年齡大於100,則不應該在該屬性中設置。在那個時間點,您需要更改基類,以及你的孩子班。這將是我們生活中最艱難的部分(代碼重構)。為了避免這些問題並使你的變量安全,從我的觀點來看,我們應該使用getter和setters.sorry來獲得長期答案
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.