【问题标题】:what are ES6 class getter and setter actually?什么是 ES6 类的 getter 和 setter?
【发布时间】:2017-05-21 22:48:37
【问题描述】:

什么是 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;
  }
}

可以做什么?

【问题讨论】:

标签: javascript ecmascript-6 setter


【解决方案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 否则,领先如果您尝试设置它,则会导致堆栈溢出。

但是你问过关于将道具定义放在一个单独的函数中,我的第一个想法是如何使用 Circle 的多个单独实例来做到这一点...

所以这是一个完整的工作示例,其中包含两个 Circle 定义,从一个单独的函数中添加道具,以及它的 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

【讨论】:

    【解决方案2】:

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

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

    getter/setter 语法适用于必须基于其他属性计算的属性,例如来自给定radius 的圆圈中的area 属性:

    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 对象的全名。你明白了。

    【讨论】:

    • 我们知道类实际上是原型的简写,在构造方法中,我们可以实例化对象。但是,我想要的是在类定义中但在构造函数方法之外在其原型中定义一个道具。
    • 不使用实例自己的属性
    • 区域设置器应该是this.radius = Math.sqrt(n / Math.PI);
    【解决方案3】:

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

    这里你只返回一个字符串“jack”,它没有绑定到任何属性。

    有趣的 console.log(Person.prototype.name) 日志杰克

    但是 Person.hasOwnProperty(name) 记录为假

    一旦我们创建了 Person 调用的实例,即 const x = new Person();

    console.log(x.name) -> 这会引发错误,无法读取属性 x.name 因为 x.hasOwnProperty(name) 是假的

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 2016-11-09
      • 1970-01-01
      • 2015-11-13
      • 2011-02-08
      • 2014-12-20
      • 1970-01-01
      相关资源
      最近更新 更多