使构造函数参数特权于ES6类方法

时间:2016-05-11 01:30:16

标签: javascript ecmascript-6

在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'

2 个答案:

答案 0 :(得分:4)

  

如果我想让这个工厂成为ES6类,我怎样才能以相同的方式揭示构造函数参数?

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

您的工厂方法与班级的方法非常不同。你不能使用一个类来达到同样的效果并且没问题。您不必使用类,因为它们存在。

答案 1 :(得分:2)

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

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

说完这一切,IMO,“私人”价值被高估了,特别是如果你不得不向后弯腰以使它们发生。最后,它们只对人类程序员有用,不会意外地“触及某人的私人”并搞乱状态。为此目的,命名约定通常是完全足够的,例如, this.__my_private = a。只是不要触摸__变量,除非它们是你的。