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);
Run Code Online (Sandbox Code Playgroud)
这是我的代码.我创建了一个getter和setter为_name成员.我没有创建一个getter和setterfor age.
但两者都可以像这样更新这两个字段 man.name = 'B';man.age = 20;
所以,我很困惑,是getter和setter必要在JavaScript?
jfr*_*d00 26
是的,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)
Run Code Online (Sandbox Code Playgroud)
考虑 API 设计者的需求——他们很可能对用户如何看待他们的 API 非常敏感。每一位(或在这种情况下,括号)都计入清理接口。
是的,它们是非常必要的。只是不是每个属性。
这里有两个使用 setter 的原因:
假设您有一个值必须是 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);Run Code Online (Sandbox Code Playgroud)
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);Run Code Online (Sandbox Code Playgroud)
<div id="output"></div>Run Code Online (Sandbox Code Playgroud)
这里有两个使用 getter 的原因:
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);Run Code Online (Sandbox Code Playgroud)
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(x.a);
const y = new MyObj('tacos');
console.log(y.a);Run Code Online (Sandbox Code Playgroud)
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);Run Code Online (Sandbox Code Playgroud)
你需要getter和setters吗?没有。它们有必要吗?是的。
| 归档时间: |
|
| 查看次数: |
5477 次 |
| 最近记录: |