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);
这是我的代码。我为getter
成员创建了setter
和_name
。我没有为getter
创建setter
和age
。
但两者都可以更新这两个字段,例如man.name = 'B';man.age = 20;
所以我很困惑,JavaScript中需要getter
和setter
吗?
答案 0 :(得分:20)
是的,getter或setter有时非常有用,但只需要在需要特定功能时使用它们 - 否则没有getter或setter的普通属性访问就可以了。
每次请求属性时,如果要运行某些代码,都会使用getter。在您的示例中,无论名称是什么情况,getter始终返回名称的大写版本,同时保留实际案例以供内部使用。
每次设置属性时,如果要运行某些代码,就会使用setter。在您的情况下,它会阻止设置假名称。没有getter / setter,您无法实现这些功能。
当您不需要getter或setter特殊逻辑时,直接属性访问是一种非常好的方法。
getter和setter也可能获取并设置一些不公开的属性(因此通过正常的属性访问根本不可用),因为它存储的位置不同(不是作为此对象的属性)或私下存储,甚至存储在其他硬件设备中。在这些情况下,getter和setter会模拟实际不存在的属性值。因此,它们简化了界面,同时允许从任何地方存储或检索实际值。
答案 1 :(得分:4)
必要吗?否。
是否有最佳表现为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过于敏感。每一点(或在这种情况下,括号)都会计入清理界面的程度。
答案 2 :(得分:0)
字母和字母r用于访问私有财产或从外部进行修改。 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}
答案 3 :(得分:0)
是的,它们是非常必要的。只是不是每个属性。
这是有二传手的两个原因:
假设您的值必须为0到100之间的整数。设置程序可以验证输入值的类型正确且在正确范围内:
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(x.a);
const y = new MyObj('tacos');
console.log(y.a);
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
吗?不,有必要吗?是的。
答案 4 :(得分:0)
实施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 ++进行黑客攻击。
答案 5 :(得分:-1)
使用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());
答案 6 :(得分:-2)
我们使用该类的原因是保存单个实体的所有属性。但是您可以通过创建对象来完成,并且可以在需要时附加属性。
当代码变大时,您无法调试代码失败的位置。如果您遵循该结构,您可以轻松地dubug.Because因为每个实体将在单独的文件中,逻辑将是独立的。
但JavaScript是一种面向对象的编程语言。我们使用类而不是对象的原因,对于getter和setter来说是相同的。它不像你可以在哪里使用你不需要的地方。这是一个很好的做法通过setter和getter设置并获取所有属性。
在某个时间点之后,您可能会在设置属性时添加一些条件,例如,如果一个人的年龄大于100,则不应该在该属性中设置。在那个时间点,您需要更改基类,这也是你孩子的课程。这将是我们生活中最难的部分(代码重构)。为了避免这些问题并使你的变量安全,从我的角度来看,我们应该使用getter和setters.sorry来获得长期答案