有没有办法将JS属性的setter/getter抽象到对象的原型中?



我正在尝试在节点中创建一个非常简单的类。该课程称为学生,其中包含一些我希望私下的变量。因此,我没有将它们标记为

this.field = "";

但是

let field = "";

我读到可以在构造函数中创建对象的属性:

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

在基本层面上正常工作。但是,我注意到,每个学生的实例都会在内存中生成全新的固定器和捕获器,这是创建许多实例时效率高的效率。

我还读取了归因于原型对象的函数。但是,每当我尝试将其设置为原型时(通过替换此(:

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

创建2个或多个实例时,它会失败,引用" TypeError:无法重新定义属性"。出了什么问题,我该怎么办才能使此代码尽可能高效?最好在构造函数函数中具有所有代码。

编辑:导致其失败的简单测试。

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

在构造函数中创建的局部变量是为了隐私的目的,无法通过原型上的共享方法访问。这些变量不在添加到原型的方法范围内。

,而且,正如您所知道的那样,在构造函数中的原型中添加东西也无法正常工作。最好的做法(如果没有错误失败(是创建一个单个方法,所有对象使用只能访问最后一个对象(这确实很糟糕且具有误导性(。

构造函数中的私有属性只能通过分别添加到构造函数内的对象中的方法(这只是正常的JavaScript范围范围的声明变量规则(访问,这意味着可以对方法进行重复的副本。

因此,您必须选择要优化的内容。您要么在构造函数中声明了私有变量,要么在原型上使用仅访问对象的常规属性的方法,但是原型上无法直接访问构造函数中的这些私有变量。