简体   繁体   English

有没有一种方法可以将JS属性的设置器/获取器抽象到对象的原型?

[英]Is there a way to abstract the setters/getters of a JS property to the Object's prototype?

I am trying to create a very simple class in Node. 我正在尝试在Node中创建一个非常简单的类。 The class is called Student and it contains a few variables which I wish to keep private. 该类称为Student,它包含一些我希望保持私有状态的变量。 Thus, I have not labeled them as 因此,我没有将它们标记为

this.field = "";

but rather 反而

let field = "";

I read that properties of an object could be created inside the constructor like so: 我读到可以在构造函数内部创建对象的属性,如下所示:

exports.student = function Student(firstName, lastName, ID, courses){

if(courses.length < 2) throw "Not enough courses supplied!";

let _firstName= firstName || "";
let _lastName = lastName || "";
let _ID = ID || 0;
let _courses = courses || [];

Object.defineProperties(this, {
  firstName: {
      get: () => {return _firstName;},
      set: (name) => {_firstName = name; return this}
  },
  lastName: {
      get: () => {return _lastName},
      set: (name) => {_lastName = name; return this}
  },
  ID: {
      get: () => {return _ID},
      set: (name) => {_ID = name; return this}
  },
  courses: {
      get: () => {return _courses}
  }
});
};

Which works fine on a basic level. 在基本水平上可以正常工作。 However, it came to my attention that every instance of Student will generate entirely new setters and getters in memory, something highly inefficient when many instances are created. 但是,引起我注意的是,每个Student实例将在内存中生成全新的setter和getter,当创建多个实例时,效率极低。

I have also read functions attributed to the Prototype Object are created once only; 我还阅读了归因于原型对象的函数仅创建一次; however, whenever I attempt to set these to the prototype like so (by replacing this): 但是,每当我尝试将它们设置为原型时(通过替换):

function Student(){...
    Object.defineProperties(Student.prototype, {...});
}

It fails when 2 or more instances are created, citing "TypeError: Cannot redefine property". 当创建两个或更多实例时,它会失败,并引用“ TypeError:无法重新定义属性”。 What is going wrong, and what can I do to make this code as efficient as possible? 出了什么问题,我该怎么做才能使此代码尽可能高效? It would be preferable to have all the code inside the constructor function. 最好将所有代码都包含在构造函数中。

Edit: The simple tests that are causing it to fail. 编辑:导致它失败的简单测试。

let a = new Student("A", "S", 1, [1, 2]);
let b = new Student("G", "X", 0, [3, 2]);
console.log(a.firstName);

Local variables created in the constructor for purposes of privacy cannot be accessed by shared methods on the prototype. 原型上的共享方法无法访问在构造函数中出于隐私目的创建的局部变量。 Those variables are not in the scope of methods added to the prototype. 这些变量不在添加到原型的方法的范围内。

And, as you have figure out, adding things to the prototype in the constructor is not going to work either. 而且,如您所知,在构造函数中向原型添加内容也不起作用。 The best that would do (if it doesn't fail with an error) is create a single method that all object use that has access to only the last object created (which is really bad and misleading). 最好的办法(如果它不会因错误而失败)是创建一个单一方法,所有对象使用该方法只能访问最后创建的对象(这确实很糟糕并且具有误导性)。

Private properties in the constructor can only be accessed by methods added individually to the object within the scope of the constructor (this is just normal Javascript scoping rules for declared variables) which means making duplicate copies of the methods. 构造函数中的私有属性只能通过在构造函数范围内单独添加到对象中的方法来访问(这只是声明的变量的常规Javascript范围规则),这意味着制作方法的重复副本。

So, you have to pick what you want to optimize for. 因此,您必须选择要优化的内容。 Either you have private variables declared in the constructor or you use methods on the prototype that only access regular properties of the object, but you can't have methods on the prototype that can access those private variables in the constructor directly. 要么在构造函数中声明了私有变量,要么在原型上使用了仅访问对象常规属性的方法,但是原型上没有可以直接在构造函数中访问这些私有变量的方法。

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

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