原型模式中的 getter 和 setter

Getters & Setters in a prototype pattern

我想在原型模式中使用 getter 和 setter。我通过在构造函数中放置 Object.defineProperty 来做到这一点。

我知道我可以在原型对象中创建 getWhatever() 方法,因为我喜欢通过真实 getters/setters

访问属性的简洁性

但是像这样在原型对象之外设置 defineProperty 对我来说并不合适。有没有更好的方法?

function Person(name) {
    this._name = name;

    Object.defineProperty(this, 'name', {
        get: function() {
            return this._name;
        }
    });
}

笨蛋:https://plnkr.co/edit/h3tgJjQBGspepdho3lqJ?p=preview

为什么不在原型本身上做呢?

function Person(name){
    this._name = name;
}

Object.defineProperty( Person.prototype, 'name', {
    get:function(){ return this._name; }
})

ES6 classes 与模块的组合可用于创建真正的 私有成员,在原型 上具有 getter。

The WeakMap object is a collection of key/value pairs in which the keys are objects only and the values can be arbitrary values.-MDN

const _name = new WeakMap(); 

class Person {
  constructor(name) {
    _name.set(this, name); // Set key to THIS and value to name. 
  }

  // Members in class body are automatically on prototype.
  get name() {
    return _name.get(this); // Get value (name) via key (THIS).
  }
}

const p = new Person('Betti');

p.name;  // Betti
p.name = 'Toni';
p.name;  // Betti

为了防止访问名称 WeakMap,我们可以将其与人 class 一起放在他们自己的模块中(单独的文件称为 person.js)。 然后我们只导出 class,因此无法访问 WeakMap。

在person.js中:

const _name = new WeakMap();

export class Person { ... }

并将其导入到我们需要 class 的任何地方。

在script.js中:

import {Person} from './person';

不使用 Webpack 的解决方法:

在人后添加“.js”

import {Person} from './person.js';

并在我们的 html 文件中,将脚本类型更改为 "module"

<script type="module" src="script.js"></script>

(不确定在生产中是否建议使用变通方法,可能最好使用 Webpack)

来源:Moshes JS OOP 课程。