原型上的Javascript私有成员 [英] Javascript private member on prototype

查看:101
本文介绍了原型上的Javascript私有成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚这是否可行。这是代码:

Well I tried to figure out is this possible in any way. Here is code:

a=function(text)
{
   var b=text;
   if (!arguments.callee.prototype.get)
      arguments.callee.prototype.get=function()
    {
         return b;
    }
    else
      alert('already created!');
}

var c=new a("test");  // creates prototype instance of getter
var d=new a("ojoj");  // alerts already created
alert(c.get())        // alerts test 
alert(d.get())        // alerts test from context of creating prototype function :(

如你所见,我试图创建原型getter。为了什么?好吧,如果你写这样的东西:

As you see I tried to create prototype getter. For what? Well if you write something like this:

a=function(text)
{
    var b=text;
    this.getText=function(){ return b}
}

......一切都应该没问题......但事实上每次我创建对象 - 我创建使用内存的getText函数。我想在内存中有一个原型函数可以做同样的...任何想法?

... everything should be fine.. but in fact every time I create object - i create getText function that uses memory. I would like to have one prototypical function lying in memory that would do the same... Any ideas?

编辑:

我尝试过Christoph给出的解决方案,它似乎是目前唯一已知的解决方案。它需要记住id信息以从上下文中检索值,但是整个这个想法对我很好:)我只记得一件事,其他一切都可以存储在内存中。实际上,您可以通过这种方式存储许多私有成员,并且只能使用一个id。实际上这让我很满意:)(除非有人有更好的主意)。

I tried solution given by Christoph, and it seems that its only known solution for now. It need to remember id information to retrieve value from context, but whole idea is nice for me :) Id is only one thing to remember, everything else can be stored once in memory. In fact you could store a lot of private members this way, and use anytime only one id. Actually this is satisfying me :) (unless someone got better idea).

someFunc = function()
{
  var store = new Array();
  var guid=0;
  var someFunc = function(text)
  {
    this.__guid=guid;
    store[guid++]=text;
  }

  someFunc.prototype.getValue=function()
  {
    return store[this.__guid];
  }

  return someFunc;
}()

a=new someFunc("test");
b=new someFunc("test2");

alert(a.getValue());
alert(b.getValue());


推荐答案

JavaScript传统上没有提供隐藏属性的机制( '私有成员')。

JavaScript traditionally did not provide a mechanism for property hiding ('private members').

由于JavaScript是词法范围的,你总是可以通过使用构造函数作为你私有的闭包在每个对象级别上模拟它成员'和在构造函数中定义你的方法,但这对构造函数的prototype属性中定义的方法不起作用。

As JavaScript is lexically scoped, you could always simulate this on a per-object level by using the constructor function as a closure over your 'private members' and defining your methods in the constructor, but this won't work for methods defined in the constructor's prototype property.

当然,有办法解决这个问题。 ,但我不推荐它:

Of course, there are ways to work around this, but I wouldn't recommend it:

Foo = (function() {
    var store = {}, guid = 0;

    function Foo() {
        this.__guid = ++guid;
        store[guid] = { bar : 'baz' };
    }

    Foo.prototype.getBar = function() {
        var privates = store[this.__guid];
        return privates.bar;
    };

    Foo.prototype.destroy = function() {
        delete store[this.__guid];
    };

    return Foo;
})();

这会将'private'属性存储在与 Foo分开的另一个对象中实例。确保在完成对象后调用 destroy():否则,您刚刚创建了内存泄漏。

This will store the 'private' properties in another object seperate from your Foo instance. Make sure to call destroy() after you're done wih the object: otherwise, you've just created a memory leak.

编辑2015-12-01: ECMAScript6改进了不需要手动对象销毁的变体,例如使用弱地图或最好是符号,完全不需要外部存储:

edit 2015-12-01: ECMAScript6 makes improved variants that do not require manual object destruction possible, eg by using a WeakMap or preferably a Symbol, avoiding the need for an external store altogether:

var Foo = (function() {
    var bar = Symbol('bar');

    function Foo() {
        this[bar] = 'baz';
    }

    Foo.prototype.getBar = function() {
        return this[bar];
    };

    return Foo;
})();

这篇关于原型上的Javascript私有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆