如何在javascript中从IFFE访问私有属性

时间:2014-10-23 22:44:59

标签: javascript

我正在玩一个在对象声明中使用IFFE而不是我必须在声明结束时手动调用的init()方法的想法。我似乎唯一的问题是我不知道如何从IFFE中访问私有财产。请看以下示例:

function Obj() {

    this.prop = 'Public property';
    var _prop = 'Private property';

    ( function( that ) {

        console.log( that.prop );
        console.log( that._prop ); // Returns undefined

    } )( this );

}

obj = new Obj();

通过将this传递到IFFE,我可以访问this范围,但私有属性似乎无法通过此评估。我知道我可以手动传递单个属性,但我更喜欢允许我访问所有私有属性的解决方案。

解决这个问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:1)

IIFE 是实施模块模式的方式。 (见The Module Pattern

在函数内声明的任何对象都与外部作用域隔离, 私有变量 无法访问。如果您需要修改私人对象,可以使用 IIFE 重新考虑。

现在看一下您的代码,变量_prop在同一 closure 中声明,其中 IFFE 已定义,这意味着您可以在 IIFE 中访问该对象,例如

function Obj() {
    var _private = 1;

    //IIFE
    (function() {
        console.log("_private: ", _private);
    }());
}

此外,您可以创建一个修改私有对象的公共方法,例如

function Obj() {
    var _seed = 0;
    this.setSeed = function (seed) {
        _seed = seed;
    };
    this.getSeed = function() {
        return _seed;
    };
}

或者您可以在实例原型中定义 getter / setter ,但这种方法的缺点是性能较低,例如

function Obj() {
    var _seed = 0;
    Object.defineProperty(this, "seed", {
        get: function () { return _seed; },
        set: function (seed) {
            //ensure to be a numeric value
            if (+seed || seed === 0) _seed = +seed;
        }
    });
}

或使用 loose augmentation

创建模块
//begin IIFE
var module = (function (module) {
    var _private = 1;

    function getPrivate() {
        return _private;
    }

    function setPrivate(value) {
        _private = value;
    }

    function printPublicMember() {
        console.log(module.publicMember);
    }

    //public mudule API
    module = {
        "publicMember": "I am public!!",
        "printPublicMember": printPublicMember,
        "getPrivate": getPrivate,
        "setPrivate": setPrivate
    };

    return module;

}(window.module || {}));
//end IIFE

答案 1 :(得分:1)

正如@jherax所说,使用IFFE的目的是近似于JavaScript中的块级范围,因此访问IFFE之外的私有属性会破坏拥有IFFE的目的。

但是,您可以通过返回指向相关属性的对象来创建排序API。使用不当这是一个黑客攻击,通常不鼓励。

function Obj() {

this.prop = 'Public property';
var _prop = 'Private property';

  ( function( that ) {

    console.log( that.prop );
    console.log( that._prop ); // Returns undefined

  } )( this );
  return {
    accessPoint: _prop //gives you a getter of sorts to _prop
  };
}

obj = new Obj();
obj.accessPoint;

答案 2 :(得分:0)

由于:

var _prop = 'Private property';

创建一个局部变量和

    console.log( that._prop ); // Returns undefined

正在尝试访问_prop属性(又名)。变量不是对象属性*。使用:

    console.log( _prop ); // Returns Private property

答案 3 :(得分:0)

构造函数中的IIFE没有任何意义。它完全等同于直接编写其内容。 IIFE的目的是创建一个包含局部变量的封闭范围,这是您不具备的。

这个IFFE应该以什么方式避免调用某些init函数?构造函数已经以自己的方式成为init函数。

您无法从IIFE中访问that._prop的原因是没有名为_prop的实例属性。有一个名为_prop的局部变量,要访问它,只需说出_prop,而不是this._propthat._prop