什么是ES6类getter和setter呢?

时间:2017-01-07 05:28:06

标签: javascript ecmascript-6 setter

ES6类定义中实际的getter和setter方法是什么?他们是原型道具吗?为考试:

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;
  }
}

可以做些什么?

3 个答案:

答案 0 :(得分:18)

是的,可以这样做:只需删除setter / getter语法并在初始化期间向类添加属性:

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

必须根据其他属性计算属性的getter / setter语法,例如来自给定area的圆圈的radius属性:

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);
    }
}

或获取具有PersonfirstName属性的lastName对象的全名。你明白了。

答案 1 :(得分:2)

根据MDN,get语法将对象属性绑定到将在查找该属性时调用的函数。

在这里你只返回一个字符串' jack'它不对任何财产具有约束力。

有趣的是console.log(Person.prototype.name)记录插孔

但是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

答案 2 :(得分:0)

我知道这是一个较晚的回复,但看起来没有人跟进您的回复:

我们知道类实际上是构造函数中原型的简写 方法,我们可以实例化对象。但是,我想要的是 在类定义内但在原型之外的原型中定义道具 构造方法

您可以像以前一样继续声明该类:

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);
        }
    }
});

或您想要的任何获取器和设置器。

我给 actual _radius成员加了下划线,以区别于它是成员变量,而不是要添加的radius属性,因为它们都是这样。否则会导致半径变大,如果尝试对其进行设置,则会导致堆栈溢出。

但是您问过将道具定义放在一个单独的函数中的问题,我的第一个想法是如何使用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