【问题标题】:Javascript OOP - non-privileged public methods with private variablesJavascript OOP - 具有私有变量的非特权公共方法
【发布时间】:2015-11-16 22:20:54
【问题描述】:

我正在尝试找到一种 javascript OOP 方法,其中变量应该是私有的(不能从外部访问),使用非特权方法。

下面的例子应该演示一下:

var Person = (function() {
var _name;
var _surname;
var _personID;
function Person(name, surname, personID) {
    _name = name;
    _surname = surname;
    _personID = personID;
}
Person.prototype.getName = function() {
    return _name;
};
Person.prototype.getSurname = function() {
    return _surname;
};
Person.prototype.getPersonID = function() {
    return _personID;
};
return Person;
})();

//Testing
var max = new Person('Max', 'Smith', 2345);
max._name = 'John';
console.log(max.getName()); // Max
console.log(max.getSurname()); // Smith
console.log(max.getPersonID()); // 2345

似乎满足条件,所以max._name = 'John'没有改变值,方法仍然获取私有值(不使用.this)

但是,问题是,创建另一个对象显然是同一个对象,它引用相同的值:

//Testing
var max = new Person('Max', 'Smith', 2345);
var max2 = new Person('Max2', 'Smith2', 2345);

console.log(max.getName()); // Max2
console.log(max.getSurname()); // Smith2
console.log(max.getPersonID()); // 2345

console.log(max2.getName()); // Max2
console.log(max2.getSurname()); // Smith2
console.log(max2.getPersonID()); // 2345

如何在不公开值的情况下创建不同的对象?在 Javascript 中是否有可能?

【问题讨论】:

  • “在 Javascript 中完全可以吗?” 当然可以,但是您会失去其他好处。我建议不要将其他语言的概念强加到 JavaScript 上。
  • 封装不必在语言级别强制执行。您可以在文档级别执行此操作。例如/* Variables begins with _ are private. DO NOT modify them outside this class or you will be fired */

标签: javascript oop


【解决方案1】:

在 Javascript 中是否有可能?

不,不是。停止搜索,您将永远找不到方法。
只要使用特权方法,它们没有任何问题。

【讨论】:

  • 我也已经倾向于使用特权方法了。使用 Object.freeze 将一些私有方法公开是一种好方法吗?看看 Geoffrey Ochsner 的方法吧。
  • 使用 Object.freeze,使一些私有方法公开”对我来说没有意义。 Geoffrey 的回答基本上是使用可以与寄生继承一起使用的工厂模式,但这与默认的构造函数+原型方法在变量隐私或特权方法的使用方面没有什么不同。
  • 也就是说,Object.freeze 不应该造成任何伤害 - 只要您以后不想扩展对象,例如继承,并且只要它没有明显的性能影响。就我个人而言,我从未遇到过必须使用Object.freeze 来防范任何事情的情况。
【解决方案2】:

也许这就是您要找的。我还包括一些动物代码来演示如何进行继承。实际上,我认为您可以删除“新”关键字(尽管它可能会在幕后重新添加,不确定)。

http://plnkr.co/edit/6nW3DtqJWEu7fZ29GMOC?p=preview

var Person = (function(){
  function Person(name, surname, personId){
    var _name = name, _surname = surname, _personId = personId;

    return Object.freeze({
      getName: getName,
      getSurname: getSurname,
      getPersonID: getPersonID
    });

    function getName(){
      return _name;
    }

    function getSurname(){
      return _surname;
    }

    function getPersonID(){
      return _personId;
    }
  }

  return Person;
})();

var max = new Person('Max', 'Smith', 2345);
var max2 =  Person('Max2', 'Smith2', 2346);
max._name = 'John';
console.log(max.getName()); // Max
console.log(max.getSurname()); // Smith
console.log(max.getPersonID()); // 2345

console.log(max2.getName()); // Max2
console.log(max2.getSurname()); // Smith2
console.log(max2.getPersonID()); // 2346

编辑:我不确定我的解决方案是否符合 Douglas Crockford's definition 的“非特权”条件。我确实认为该页面已经过时,我正在使用他的新语法 Object.freeze() 这意味着不再可能删除或更改公共方法。

Edit2:我无耻地从The Better Parts 窃取了该语法。给它一个手表。

【讨论】:

  • 我认为,您在这里使用的是特权方法,在这种情况下,Person 的外部范围是无用的,因为特权函数已经在 Person 的构造函数中。 Object.freeze 方法很好,它将指定的方法公开。您是否认为 Object.freeze “方法”(将可见)和特权方法(如 this.getPersonID = function(){})之间存在差异? (感谢您的发帖)
  • 如果您查看 Douglas Crockford 对“特权”方法的定义,他使用的是“this”语法。他说“可以删除或替换一个特权方法,但不可能改变它,或者强迫它放弃它的秘密。”使用他更新的语法,就像我一样,不可能删除或更改属性(据我所知)。
猜你喜欢
  • 2012-09-03
  • 2011-12-03
  • 2013-05-03
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
  • 2011-05-25
  • 2012-05-29
  • 1970-01-01
相关资源
最近更新 更多