是否有可能通过立即调用的函数表达式
考虑下面的代码的执行上下文:是否有可能通过立即调用的函数表达式
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
})();
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
我想有IIFE的执行上下文在我的全局对象。我有权访问函数表达式和对象本身,因此我可以传递或修改某些内容以使其工作(并且不,我不能重写对象或函数内的所有内容)。
这有可能吗?
我看到这种方式的可行性的唯一方法是使用eval
来模拟动态范围。做到这一点(注意,IIFE必须在全局对象之后放置):
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
eval("(" + String(window.myGlobalObj.init) + ")").call(window.myGlobalObj);
})();
这里有一个参考关于如何使用动态范围:Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?
编辑:我已经包括了一个例子来展示在JavaScript中使用动态范围的强大功能。你也可以玩fiddle。
var o = {
init: function() {
alert(a + b === this.x); // alerts true
},
x: 5
};
(function() {
var a = 2;
var b = 3;
eval("(" + String(o.init) + ")").call(o);
}());
尽管我实际上并没有在应用中实际使用这种方案,但这非常有趣,学到了一些新东西! – 2012-04-23 11:44:57
很高兴为您提供帮助。如果你愿意更多地了解'eval'以及如何安全地使用它,那么可以利用很多黑客。例如,你可以实现[指针](http://hpyblg.wordpress.com/2010/05/31/simulating-pointers-in-javascript-part-2/“模拟JavaScript中的指针,第2部分«快乐博客,快乐博客“)在JavaScript中使用'eval'。 – 2012-04-23 11:51:41
@Stonerain,你刚刚学会了非常讨厌的事情。躲开它!埃瓦尔被道格拉斯克罗克福德这样的大师们所诟病。该代码很难看,很难理解和调试,效率低下并带来其他危险。为此使用它是滥用。 – TMS 2012-04-24 07:05:31
您的IIFE的“内容”,即a
,someFunc
等等对于该功能范围而言是本地的,因此您只能在该范围内访问它们。但是,你可以指定window.myGlobalObj
的IIFE内:
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
})();
然后init
功能将有机会获得这些变量,因为他们是在其包含的范围。
编辑:如果你不能的myGlobalObj
定义移动到IIFE我能想到的是唯一使用IIFE创建您从myGlobalObj
访问第二全局对象:
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
// create a global object that reveals only the parts that you want
// to be public
window.mySecondObject = {
someFunc : someFunc,
anotherFunc : anotherFunc
};
})();
window.myGlobalObj = {
init: function() {
window.mySecondObject.someFunc();
}
};
现在,这将工作,但我不能重写对象内的所有内容(或在这种情况下在IIFE内)。 – 2012-04-23 10:54:57
好的,对不起。我已经用我能想到的唯一其他东西更新了我的答案... – nnnnnn 2012-04-23 11:04:29
@编辑:我将不得不列出所有我想访问的变量和函数,对吧? ( – 2012-04-23 11:06:36
不,这是不可能的。你想访问的上下文被称为closure
,并且只能在函数内访问(在你的情况下,匿名函数(IIFE如何调用它))。关于关闭的更多信息,请参阅优秀的Douglas Crockfords The Javascript programming language video tutorial。
您将不得不将这些属性放置到某个共享对象。
实际上它是可能的,你所需要做的就是模拟动态我知道'eval'被认为是邪恶的,但有些情况下它是必要的,甚至jQuery使用'eval'。在JavaScript中模拟动态范围是使用'eval'确实安全的情况之一。你可以从这里阅读更多关于它:[是否有可能实现JavaScript的动态作用域而不诉诸于eval?](http://stackoverflow.com/q/10060857/783743“是否有可能在JavaScript中实现动态作用域诉诸eval?“) – 2012-04-23 11:25:46
@AaditMShah,这将是一个不好的做法!我会称之为肮脏的黑客并禁止它。顺便说一下,jQuery中用于JSON解析的eval的使用被认为是一个很大的弱点,jQuery因此受到批评。这就是为什么最好使用[Douglas Crockford的json2.js](http://json.org/)来达到这个目的。 – TMS 2012-04-23 11:31:16
随着你的回答你实际上表明我是对的 - 这是不可能的(*在合理理智的代码*内)。 – TMS 2012-04-23 11:37:56
什么是IIFE?请明确 – TMS 2012-04-23 10:44:48
@Tomas立即调用的函数表达式 – kapa 2012-04-23 10:45:16
显示了您对“访问IIFE上下文”的含义的示例。你将如何访问它。 – TMS 2012-04-23 10:46:24