1

在我们的代码库中,我发现许多开发人员使用下划线作为成员变量的首字母来阻止公共使用。通常,更好的做法是声明一个对象的方法可以访问的局部变量,但在我们的例子中,这似乎是不可能的,因为所有方法都是在原型上定义的。这是一个例子。

MyContrivedWidget = function(container) {
  this._container = jQuery(container);
}

MyContrivedWidget.prototype = {
  draw: function() {
    var link = jQuery(document.createElement('a'))
      .html('some contrived text')
      .attr('href', '#')
      .appendTo(this._container);
  }
}

我们使用原型对象有多种原因,但最引人注目的可能是使用原型链可以轻松继承和覆盖方法。这对我们有好处,因为我们在一个平台上有多个产品,可能希望在覆盖特定功能的同时重用大量 JavaScript。

所以我的问题是,我们如何才能获得原型链的所有好处而不让应该私有的变量可以公开访问?

4

1 回答 1

1

简单地说:ECMAscript 第 3 版不可能使用原型继承或原型链创建“私有”变量。

在 ES5 中有点不同。你有像.defineProperties()help这样的方法,它们能够在对象中“隐藏”属性。

但是,即使您将这些属性隐藏起来,例如,如果他知道这些属性可用,他仍然可以访问这些属性。正如您所提到的,ECMAland 中唯一真正的隐私是调用闭包。更好的说法是,通过调用一个函数(-context)来使用方法模式,该函数返回一个包含方法作为属性的对象。这些方法可以访问(因为它的上下文关闭了父上下文)在外部(父)范围内声明的变量。之后没有其他对象可以访问这些变量。这看起来像:

var Animal = function( args, priv, shared ) {
    shared = shared || { };
    shared.speed = 2;
    shared.legs = 4;
    shared.name = args.name || 'unknown'; 

    priv = priv || {
        run: function() {
            console.log(shared.name, ' is running ', shared.speed, ' meters');
            return this;
        },
        die: function() {
            console.log(shared.name, ': wwuuaarhhhck.. aahahsd sd..aahsd.....');
            return this;
        }
    };

    return priv;
};

var Dog = function( args, priv, secret ) {
    secret = secret || { };

    priv = Animal( args, priv, secret ) || { };

    priv.addSomeMethod = function() { };

    return priv;
};

var bello = Dog({name: 'Bello'});
bello.die(); // "Bello:  wwuuaarhhhck.. aahahsd sd..aahsd....."

有一些很棒的模式可以扩展这个想法,它们也提供继承和共享对象+超级方法。这种编程的良好开端仍然是 Douglas Crockfords “Javascript:好的部分”。

于 2011-06-21T15:56:22.610 回答