JavaScript封装-以任何方式访问给定实例的私有成员?

问题描述

| 给定实例变量,是否可以访问javascript中的私有成员?例如,
function class Foo() {
   var x=12;
   // some other stuff
}
F = new Foo();
// how to get/set F.x?
更新:作为一个转折点,假设该类具有特权方法。是否有可能劫持该特权方法以访问私有成员?
function class Foo() {
   var x=12,y=0;
   this.bar = function(){ y=y+1; }
}
F = new Foo();
// can I modify Foo.bar to access F.x?
    

解决方法

您将需要一个特权方法来获取/设置
x
的值:
function Foo() {
    var x = 12;
    this.getX = function() { return x; };
    this.setX = function(v) { x = v; };
}

var f = new Foo(),g = new Foo();

f.getX(); // returns 12
g.getX(); // returns 12

f.setX(24);

f.getX(); // returns 12
g.getX(); // returns 24

g.setX(24); 

f.getX(); // returns 24
g.getX(); // returns 24
现场演示:http://jsfiddle.net/simevidas/j7VtF/     ,如果您确实想要这样的访问,则可以执行以下操作,但是我不建议这样做:
function Foo() {
     var x = 12;
     this.runContext = function(f) {
          return eval(f);
     };
}

var f = new Foo();
f.runContext(\'alert(x);\');
    ,您可以按某种模式编写代码以实现此目的。 我将在下划线的帮助下进行演示。
function Construct() {
    this.foo = \"foo\";
    this._private = \"bar\";

    this.method = function() {
        return 42;
    };

    this._privateMethod = function() {
        return \"secret\";
    };

    var that = this;
    var inject = function(name,f) {
        this[name] = _.bind(f,that);
    };

    _.bindAll(this);

    return {
        \"foo\": this.foo,\"method\": this.method,\"inject\": inject
    };
}

var c = new Construct();
console.log(c.foo); // foo
console.log(c.method()); // 42
c.inject(\"foo\",function() {
    console.log(this._private);
    console.log(this._privateMethod());
});
c.foo(); // bar,secret
现场例子 基本上,这里有两个对象。您的真实对象和代理对象将传递给客户端。代理只能通过代理方法和变量来访问真实状态。 但是它确实有一个注入方法,允许您将方法从代理注入到真实对象上     ,在您的示例中,变量
x
对于构造函数是局部的,并且一旦该函数超出范围,就不会保留其值。但是,您可以将值分配给对象的命名属性,例如:
var Foo = function() {
  this.x = 12;
}
var f = new Foo();
f.x; // => 12
f.x = 123; // => 123
    ,javascript中的私有成员已附加到对象,但外部无法访问它们,对象本身的公共方法也无法访问它们。私有方法可以访问它们。私有方法是构造函数的内部函数。 您需要一个公共函数,该函数访问私有内部函数,该内部函数最终将访问私有成员。 参考:访问Java中私有成员的更好方法