JavaScript 中的隐私性

发布于 2024-10-19 10:10:10 字数 250 浏览 1 评论 0原文

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

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

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

但使用起来有那么糟糕吗?因为没有办法让它真正私有。

您对此有何看法?你如何处理?

I know you can achieve something as "privateness" in JavaScript by using closures and Immediate Invoked Functions.

But what if I need full featured prototyping? There simply is no way I know of of having private members in an object's prototype. If I used privileged methods I can have private variables and public methods but I lose the option of prototyping.

Douglas Crockford "forbids" the use of dangling (putting an underscore in front of an identifier to indicate that it is not part of the public interface).

But is it that bad to use it? Since there is no way to make it real private.

What is your opinion about this? How do you handle it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱的故事 2024-10-26 10:10:10

首先,使用函数继承模式时,您并不会真正失去原型效果。我只是假设您正在谈论好的部分,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();

您甚至可以简单地扩展此技术以拥有某种超级方法。一般来说,使用像下划线之类的神秘变量约定是不好的做法。这很令人困惑,因为没有人知道那里发生了什么(如果你是唯一使用代码库的人,这个论点可能会失败)。


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

var Human = {};

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

现在,属性 privateStuff 对于继承自 Human 原型链的对象不可见。无论如何,这个东西需要 Javascript 1.8.5,并且目前仅在最先进的浏览器中可用。请参阅 https://developer.mozilla.org/en/JavaScript/Reference/ Global_Objects/对象/defineProperty

Well at first, you don't really lose the prototyping-effect when using a functional-inheritance pattern. I just assume you're talking about The good parts, crockford also introduced a pretty easy and effective way to have shared variables for that pattern aswell. Which basically looks like:

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();

You can even simply extend this techniqe to have somekind of super methods. Using cryptic variable-conventions like underscores or whatnot is just bad practice in general. Its confusing since nobody just knows what is going on there (probably that argument fails if you're the only one using the codebase).


However, ECMAscript Edition 5 introduces some goodys to have more "private" members in a prototype chain. One important method for that is .defineProperty, where you can define a property which does not "shallow" through. Would look like:

var Human = {};

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

Now, the property privateStuff is not visible for an object that inherits from Human's prototype chain. Anyway, this stuff requires Javascript 1.8.5 and is only available in cutting edge browsers for now. See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty

不回头走下去 2024-10-26 10:10:10

您可能对 JavaScript 设计模式感兴趣。它还讨论了模块模式

You may be interested in JavaScript Design Patterns. It discusses the Module Pattern too.

嗫嚅 2024-10-26 10:10:10

以下是如何允许原型函数访问所有浏览器中的私有变量的示例:

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());

这与我在 jPaq

Here is an example of how to allow prototypal functions to access private variables in all browsers:

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());

This is the same way that I implemented the Color class in jPaq.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文