6

所以,这里的第一个问题 - 请温柔。

我正在与来自各种非 Web 编程背景的其他一些开发人员一起开发一个相当繁重的 JavaScript 项目,我们决定尝试在我们的 JavaScript 伪类中使用公共和私有方法和属性,纯粹作为一种良好的编码实践(即,我们知道它没有实际的优势或安全性)

我们玩弄了几种不同的公共和私有方法(即使用局部范围的变量和具有特权方法的函数以供公共使用),我们目前已经决定让我们的 JavaScript 类构造函数实际返回一个仅代表它们的对象公共接口,有效地隐藏其他所有内容。

这是一个例子:

function MyObject()
 {
  var _this = this;

  this._privateProperty = 'somevalue';

  this._privateMethod = function()
  {
   // Do Something
  }

  this.public = 
  {
   publicProperty : _this._privateProperty,
   publicMethod : function(){ return _this.privateMethod() }
  }

  return this.public;
 }

在 Chrome 中实例化并登录时:

 var obj = new MyObject();
 console.log(obj);

输出:

> Object
    > publicMethod: function (){ return _this.privateMethod() }
    > publicProperty: "somevalue"
    >__proto__: Object

现在我的问题是:因为从构造函数返回公共接口作为新对象,所以当您 console.log 时,您会注意到它将自己标识为> Object- 而如果我们不返回该公共接口,它被标识为> MyObject.

理想情况下,我们希望显示后者以用于调试目的,并且我知道如何使用 访问构造函数的“MyObject”名称_this.constructor.name,但不知道如何设置它以便以这种方式识别。

有谁知道如何手动设置这个?

注意
我知道这在某些方面是 JavaScript 约定的混蛋,并试图在圆孔中安装一个方形钉,但我们发现它是一种非常明显且易读的方式来完成我们想要做的事情。我对如何使用不同的设计来实现这一点持开放态度,但我最终会寻找适合我们当前设计的答案。

4

3 回答 3

3

您应该能够设置 obj 的“toString”函数。例如

obj.constructor.prototype.toString = function() { return "MyObject"; }

这将使 console.log 显示“MyObject”而不是 Object。

于 2011-01-27T22:14:49.473 回答
3

尽管我的团队成员做出了英勇的努力,并且提供了解决方案的该站点的非常乐于助人的用户,我们仍然认为这种设计最终无法维护,而是选择了一种不太明显但达到相同结果的设计。

function MyObject()
{
    var _privateProperty = 'somevalue';

    function _privateMethod()
    {
        // Do Something
    }

    // Public Interface
    this.publicProperty = _privateProperty;
    this.publicMethod = _privateMethod; 

}

通过这种方法,我们基本上默认将每个属性和方法设为私有,并且在我们的“类”的底部,我们公开了我们想要公开的那些。我想大多数人都会同意这比我们最初的设计更好地遵循了正常的 JavaScript 约定,这希望这意味着它更容易被其他人阅读和维护。

再次感谢那些花时间尝试提出解决方案的人。

于 2011-01-29T00:07:54.433 回答
1

这有点奇怪(但是,你现在可能已经习惯了 :-) 但你可以用本地构造函数覆盖实际的“MyObject”构造函数:

function MyObject() {
  function MyObject(p) {
    for (var k in p) if (p.hasOwnProperty(k)) this[k] = p[k];
  }

  this.public = new MyObject({
    publicMethod: function() { /* whatever */ },
    publicProperty: "something"
  });
  return this.public;
}

显然,您可以将大部分代码分解出来,这样您就可以拥有一个函数,给定一个执行特定类初始化的函数,将为您设置所有这些。(必须像您提议的那样维护一个没有一些库支持来处理细节的系统似乎是一件真正的苦差事,而且长期保持工作非常困难,甚至更难改变。)

于 2011-01-27T21:43:50.383 回答