简体   繁体   English

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

[英]what are ES6 class getter and setter actually?

what are actually getter and setter methods in ES6 class definition? ES6 类定义中的 getter 和 setter 方法实际上是什么? are they infact prototype props ?它们实际上是原型道具吗? for examle:例如:

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

does this equals to Person.prototype.name = 'jack';这是否等于 Person.prototype.name = 'jack';

and another question, i ve seen examples of setters which utilizes the instance's prop like:还有另一个问题,我见过使用实例道具的 setter 示例,例如:

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

i dont wanna do this way, i want something like:我不想这样做,我想要这样的东西:

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

what could be done?怎么办?

Yes, it can be done: Just drop the setter/getter syntax and add a property to the class during initialization instead:是的,可以这样做:只需删除 setter/getter 语法并在初始化期间向类添加一个属性:

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

The getter/setter syntax exists for properties that must be calculated based on other properties, like the area property from a circle of a given radius : 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);
    }
}

Or getting the full name of a Person object with firstName and lastName properties.或者获取具有firstNamelastName属性的Person对象的全名。 You get the idea.你明白了。

As per MDN , The get syntax binds an object property to a function that will be called when that property is looked up.根据 MDN ,get 语法将对象属性绑定到一个函数,该函数将在查找该属性时调用。

Here you are returning just a string 'jack' it is not binding to any property.在这里,您只返回一个字符串 'jack' 它不绑定到任何属性。

Interestingly console.log(Person.prototype.name) logs jack有趣的是 console.log(Person.prototype.name) 记录 jack

But Person.hasOwnProperty(name) logs false但 Person.hasOwnProperty(name) 记录错误

also once we create instance of Person call ie const x = new Person();同样,一旦我们创建了 Person 调用的实例,即 const x = new Person();

console.log(x.name) -> this throws error, cant read property x.name because x.hasOwnProperty(name) is false console.log(x.name) -> 这会引发错误,无法读取属性 x.name,因为 x.hasOwnProperty(name) 为 false

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

I know this is a late response, but it doesn't look like anyone followed up on your response:我知道这是一个迟到的回复,但看起来没有人跟进您的回复:

we know that class is infact a shorthand for prototype, in constructor method, we can instantilize the object.我们知道类实际上是原型的简写,在构造函数方法中,我们可以实例化对象。 however, what i want is to define a prop in its prototype within class definition but outside the constructor method然而,我想要的是在类定义内但在构造函数方法之外的原型中定义一个道具

You can just continue to declare the class as you did:您可以像以前一样继续声明该类:

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

And then define the properties like this:然后像这样定义属性:

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

or whatever getters and setters you want.或者任何你想要的 getter 和 setter。

I gave the actual _radius member a leading underscore to differentiate it as the member variable separate from the radius property being added, since they'd both be this.radius otherwise, leading to a stack overflow if you try to set it.我给了实际的_radius成员一个前导下划线,以将其区分为与添加的radius属性分开的成员变量,因为否则它们都是 this.radius,如果您尝试设置它会导致堆栈溢出。

But you asked about putting the prop definitions in a separate function , and my first thought would be how to this with multiple separate instances of a Circle...但是您询问将 prop 定义放在单独的函数中,我的第一个想法是如何使用 Circle 的多个单独实例来实现这一点...

So here is a full working example with two Circle definitions, adding the props from a separate function, along with a CodePen of it here: https://codepen.io/appurist/pen/ZEbOdeB?editors=0011所以这是一个完整的工作示例,其中包含两个 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}`);

Output of the above is:上面的输出是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM