2012-04-23 37 views
4

考虑下面的代码的执行上下文:是否有可能通过立即调用的函数表达式

(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的执行上下文在我的全局对象。我有权访问函数表达式和对象本身,因此我可以传递或修改某些内容以使其工作(并且不,我不能重写对象或函数内的所有内容)。

这有可能吗?

+0

什么是IIFE?请明确 – TMS 2012-04-23 10:44:48

+0

@Tomas立即调用的函数表达式 – kapa 2012-04-23 10:45:16

+0

显示了您对“访问IIFE上下文”的含义的示例。你将如何访问它。 – TMS 2012-04-23 10:46:24

回答

2

我看到这种方式的可行性的唯一方法是使用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); 
}()); 
+0

尽管我实际上并没有在应用中实际使用这种方案,但这非常有趣,学到了一些新东西! – 2012-04-23 11:44:57

+0

很高兴为您提供帮助。如果你愿意更多地了解'eval'以及如何安全地使用它,那么可以利用很多黑客。例如,你可以实现[指针](http://hpyblg.wordpress.com/2010/05/31/simulating-pointers-in-javascript-part-2/“模拟JavaScript中的指针,第2部分«快乐博客,快乐博客“)在JavaScript中使用'eval'。 – 2012-04-23 11:51:41

+0

@Stonerain,你刚刚学会了非常讨厌的事情。躲开它!埃瓦尔被道格拉斯克罗克福德这样的大师们所诟病。该代码很难看,很难理解和调试,效率低下并带来其他危险。为此使用它是滥用。 – TMS 2012-04-24 07:05:31

2

您的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(); 
    } 
}; 
+0

现在,这将工作,但我不能重写对象内的所有内容(或在这种情况下在IIFE内)。 – 2012-04-23 10:54:57

+0

好的,对不起。我已经用我能想到的唯一其他东西更新了我的答案... – nnnnnn 2012-04-23 11:04:29

+0

@编辑:我将不得不列出所有我想访问的变量和函数,对吧? ( – 2012-04-23 11:06:36

0

不,这是不可能的。你想访问的上下文被称为closure,并且只能在函数内访问(在你的情况下,匿名函数(IIFE如何调用它))。关于关闭的更多信息,请参阅优秀的Douglas Crockfords The Javascript programming language video tutorial

您将不得不将这些属性放置到某个共享对象。

+0

实际上它是可能的,你所需要做的就是模拟动态我知道'eval'被认为是邪恶的,但有些情况下它是必要的,甚至jQuery使用'eval'。在JavaScript中模拟动态范围是使用'eval'确实安全的情况之一。你可以从这里阅读更多关于它:[是否有可能实现JavaScript的动态作用域而不诉诸于eval?](http://stackoverflow.com/q/10060857/783743“是否有可能在JavaScript中实现动态作用域诉诸eval?“) – 2012-04-23 11:25:46

+0

@AaditMShah,这将是一个不好的做法!我会称之为肮脏的黑客并禁止它。顺便说一下,jQuery中用于JSON解析的eval的使用被认为是一个很大的弱点,jQuery因此受到批评。这就是为什么最好使用[Douglas Crockford的json2.js](http://json.org/)来达到这个目的。 – TMS 2012-04-23 11:31:16

+0

随着你的回答你实际上表明我是对的 - 这是不可能的(*在合理理智的代码*内)。 – TMS 2012-04-23 11:37:56

相关问题