我正在玩一个在对象声明中使用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
范围,但私有属性似乎无法通过此评估。我知道我可以手动传递单个属性,但我更喜欢允许我访问所有私有属性的解决方案。
解决这个问题的最佳方法是什么?
答案 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;
}
});
}
创建模块
//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._prop
或that._prop
。