Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的私有性_Javascript_Inheritance_Prototype_Closures - Fatal编程技术网

JavaScript中的私有性

JavaScript中的私有性,javascript,inheritance,prototype,closures,Javascript,Inheritance,Prototype,Closures,我知道,通过使用闭包和立即调用的函数,可以在JavaScript中实现“私密性” 但是如果我需要全功能的原型呢?我根本不知道在对象的原型中有私有成员。如果我使用特权方法,我可以拥有私有变量和公共方法,但我失去了原型的选择 Douglas Crockford“禁止”使用悬挂(在标识符前加下划线表示它不是公共接口的一部分) 但是使用它有那么糟糕吗?因为没有办法让它成为真正的私人 你对此有什么看法?您是如何处理的?您可能会感兴趣。它还讨论了模块模式。首先,在使用函数继承模式时,您不会真正失去原型效果。

我知道,通过使用闭包和立即调用的函数,可以在JavaScript中实现“私密性”

但是如果我需要全功能的原型呢?我根本不知道在对象的原型中有私有成员。如果我使用特权方法,我可以拥有私有变量和公共方法,但我失去了原型的选择

Douglas Crockford“禁止”使用悬挂(在标识符前加下划线表示它不是公共接口的一部分)

但是使用它有那么糟糕吗?因为没有办法让它成为真正的私人


你对此有什么看法?您是如何处理的?

您可能会感兴趣。它还讨论了模块模式。

首先,在使用函数继承模式时,您不会真正失去原型效果。我只是假设你说的是好的部分,crockford还介绍了一种非常简单有效的方法,让共享该模式的变量。基本上看起来像:

var Human = (function(my, priv) {
    var my   = my || {},
        priv = priv || {};

    my.privatedata = "foobar";

    priv.walk = function() {
        console.log('walking');
        return priv;
    };
    priv.talk = function() {
        console.log('blah blah');
        return priv;
    };

    return priv;
}());

var Andy = (function(my, priv) {
    var my   = my || {},
        priv = Human(my, priv);

    priv.SpecialAndyThing = function() {
        console.log('bloggin at typeofnan.com');
        return priv;
    };

    return priv;
}());

var myAndy = Andy();
myAndy.talk().SpecialAndyThing();
您甚至可以简单地扩展此技术,使其具有某种super方法。一般来说,使用诸如下划线之类的神秘变量约定是不好的做法。这是令人困惑的,因为没有人知道那里发生了什么(如果您是唯一一个使用代码库的人,那么这个参数可能会失败)


但是,ECMAscript Edition 5引入了一些Goody,以便在原型链中拥有更多的“私有”成员。其中一个重要的方法是
.defineProperty
,您可以在其中定义一个不“浅”的属性。看起来像:

var Human = {};

Object.defineProperty(Human, 'privateStuff', {
    value:      'secret',
    enumerable: false
});

现在,对于从
人类
的原型链继承的对象,属性
privateTuff
不可见。无论如何,这些东西需要Javascript 1.8.5,目前只在最先进的浏览器中可用。请参见以下示例,说明如何允许原型函数在所有浏览器中访问私有变量:

var Book = (function() {
  var $ = {};

  var Book = function(newFirst, newLast) {
    // Private variables stored in an object literal.
    var _ = {
      author_first : newFirst,
      author_last : newLast
    };

    // Public privileged method for accessing private variables.
    this._ = function(key) {
      if(key === $)
        return _;
      throw new Error("The _() function must be called internally.");
    };
  };

  // Public accessor method.
  Book.prototype.getAuthor = function() {
    var _ = this._($);
    return _.author_first + " " + _.author_last;
  };

  return Book;
})();

var bookA = new Book("Chris", "West"),
    bookB = new Book("Douglas", "Crockford");
alert(bookA.getAuthor());
alert(bookB.getAuthor());

这与我在中实现Color类的方式相同。

但是现在我为每个Human或Andy对象提供了一个单独的函数实例,不是吗?@Benjamin:是的。但这对性能或内存使用没有任何影响。“闭包和有条不紊的模式”的论点比较慢,或者诸如此类的论点在我看来是错误的。