使构造函数参数具有ES6类方法的特权

Making constructor arguments privileged to ES6 class methods

本文关键字:类方法 特权 ES6 构造函数 参数      更新时间:2023-09-26

在ES5中,我可以使用这样的工厂模式:

function factory(a) {
  return {
    say: function() {
      return console.log(a)
    }
  };
}
var instance = factory('hi');
instance.say(); // => 'hi'
instance.a; // => 'undefined'

传递给工厂的参数没有在它创建的对象上设置,因此它对所有方法定义都有特权,但对作者来说不是公共的。

如果我想让这个工厂成为一个ES6类,我该如何以同样的方式显示构造函数参数?

let hack;
class Blah {
  constructor(a) {
    //bad!
    this.a = a;
    //but even worse?
    hack = a;
    //instance method is not a class method
    this.yell = () => console.log(a);
  }
  say() {
    console.log(hack);
  }
}
let blah = new Blah('hi');
blah.a; // => 'hi'
blah.hack; // => 'undefined'
blah.say(); // => 'hi'
blah.yell(); // => 'hi'

如果我想让这个工厂成为一个ES6类,我该如何以同样的方式显示构造函数参数?

你不能。出于同样的原因,您不能使构造函数参数可用于原型方法:Scope。

您的工厂方法与类所做的非常不同。你不能用一个类来达到同样的效果,这没关系。你不必仅仅因为类的存在就使用它们。

this.yell = () => console.log(a);

这基本上也是你对当前工厂所做的。您正在返回一个具有特定实例方法的新对象,该方法覆盖特定实例特定的值。这是让它发挥作用的唯一真正方法。如果要将原型用于方法,则需要使用this来存储特定于实例的值,否则prototype上的方法无法访问该值。

话虽如此,国际海事组织认为,"私人"价值观被高估了,尤其是当你不得不竭尽全力实现这些价值观时。最终,它们只对人类程序员有用,不会意外地"触碰某人的隐私"并扰乱状态。为此,命名约定通常是完全足够的,例如this.__my_private = a。只是不要触摸__变量,除非它们是您的。