ES6类的getter和setter实际上是什么?

17

ES6类定义中的getset方法是什么?它们实际上是原型属性吗?例如:

class Person{
  constructor(){};
  get name(){
    return 'jack';
  }
  set name(){
    // ???
  }
}

这是否等同于Person.prototype.name = 'jack'?此外,我看过一些使用实例属性的setter示例,例如:

class Person{
  constructor(){
    this._name = 'jack';
  };
  get name(){
    return this._name;
  }
  set name(val){
    this._name = val;
  }
}

我不想以这种方式做;我希望有像这样的东西:

class Person{
  constructor(){};
  get name(){
    return 'jack';
  }
  set name(val){
    // like this
    // name = val;
  }
}

有什么可以做的吗?


请返回以下内容的翻译文本:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get 和 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set - Oleg Estekhin
你最后一个例子中的 name = val 中的 name 是什么?我不明白。你能解释一下你想要实现什么吗? - Felix Kling
可能是ECMAScript 6类中getter和setter有什么用?的重复问题。 - Drenmi
它们实际上是原型属性。尝试使用 Object.getOwnPropertyDescriptors(Person.prototype) - Константин Ван
3个回答

21

可以做到:只需在初始化期间放弃setter/getter语法并向类添加属性即可:

class Person{
    constructor(name){
        this.name = name;
    }
}

getter/setter语法用于需要基于其他属性计算的属性,例如给定一个半径的圆的面积属性:

class Circle {
    constructor (radius) {
        this.radius = radius;
    }
    get area () {
        return Math.PI * this.radius * this.radius;
    }
    set area (n) {
        this.radius = Math.sqrt(n / Math.PI);
    }
}

或者通过具有firstNamelastName属性的Person对象获取其完整名称。你明白了。


我们知道类实际上是原型的简写,在构造函数中,我们可以实例化对象。然而,我想要的是在类定义内部但在构造函数方法之外定义其原型中的一个属性。 - feiyuerenhai
不使用实例自身的属性 - feiyuerenhai
1
区域设置器应该是 this.radius = Math.sqrt(n / Math.PI); - alphakevin

2
根据MDN,get语法将对象属性绑定到一个函数上,在查找该属性时将调用该函数。
在这里,您只返回一个字符串“jack”,它没有绑定到任何属性。
有趣的是,console.log(Person.prototype.name)记录了jack
但是Person.hasOwnProperty(name)记录了false 另外一旦我们创建Person实例调用,即const x = new Person();
console.log(x.name)-> 这会抛出错误,无法读取属性x.name,因为x.hasOwnProperty(name)为false

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get


1
我知道回复晚了,但是似乎没有人跟进你的回复:
我们知道类实际上是原型的一种简写,在构造函数方法中,我们可以初始化对象。然而,我想在类定义中但在构造函数方法之外定义其原型中的一个属性。
您可以继续像以前那样声明类:
class Circle {
    constructor (radius) {
        this._radius = radius;
    }
}

然后像这样定义属性:
Object.defineProperties(obj, {
    radius: {
        get: function () {
          return this._radius;
        },
        set: function (n) {
            this._radius = n;
        }
    },
    area: {
        get: function () {
          return Math.PI * this._radius * this._radius;
        },
        set: function (n) {
            this._radius = Math.sqrt(n / Math.PI);
        }
    }
});

或者您想要的任何getter和setter。

我在_radius成员变量前加了一个下划线,以将其区分为与添加的radius属性不同的成员变量,因为否则它们都将是this.radius,如果您尝试设置它,会导致堆栈溢出。

但是您问如何将prop定义放在单独的函数中,我的第一个想法是如何在多个Circle实例中执行此操作...

因此,这里有一个完整的工作示例,其中包含两个Circle定义,从单独的函数添加props,以及CodePen的链接: https://codepen.io/appurist/pen/ZEbOdeB?editors=0011

class Circle {
  constructor(r) {
    this._radius = r;
    addProps(this);
  }
}

function addProps(obj) {
  Object.defineProperties(obj, {
    radius: {
      get: function () {
        return this._radius;
      },
      set: function (n) {
        this._radius = n;
      }
    },
    area: {
      get: function () {
        return Math.PI * this._radius * this._radius;
      },
      set: function (n) {
        this._radius = Math.sqrt(n / Math.PI);
      }
    }
  });
}

let circle = new Circle(7);
let circle2 = new Circle(2);

console.log(`circle radius and area are: ${circle.radius} ${circle.area}`);
circle.radius = 4;
console.log(`circle radius and area now: ${circle.radius} ${circle.area}`);
circle.area = 78.53981633974483;
console.log(`circle radius and area now: ${circle.radius} ${circle.area}`);

console.log(`circle2 radius and area are: ${circle2.radius} ${circle2.area}`);
circle2.radius = 3;
console.log(`circle2 radius and area now: ${circle2.radius} ${circle2.area}`);
circle2.area = 50.26548245743669;
console.log(`circle2 radius and area now: ${circle2.radius} ${circle2.area}`);

以上的输出内容为:

上述内容的输出为:

circle radius and area are: 7 153.93804002589985
circle radius and area now: 4 50.26548245743669
circle radius and area now: 5 78.53981633974483

circle2 radius and area are: 2 12.566370614359172
circle2 radius and area now: 3 28.274333882308138
circle2 radius and area now: 4 50.26548245743669

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接