我可以禁用特定function的ECMAscript严格模式吗?

在MDC或ECMAscript规范中,我没有发现任何关于我的问题。 也许有人知道一个更“黑客”的方式来解决这个问题。

我在我的环境中调用每个JavaScript文件的"use strict" 。 我的所有文件都是这样开始的

 (function(win, doc, undef) { "use strict"; // code & functions }(window, window.document)); 

现在,我有一个处理错误的自定义函数。 该函数使用.caller属性来提供上下文堆栈跟踪 。 看起来像这样:

 var chain = (function() { var _parent = _error, _ret = ''; while( _parent.caller ) { _ret += ' -> ' + _parent.caller.name; _parent = _parent.caller; } return _ret; }()); 

当然,在严格模式下.caller是一个不可删除的道具,当检索时会抛出。 所以我的问题是,有没有人知道如何禁用更严格的“function明智”?

"use strict"; 在被调用之后被所有函数inheritance。 现在只要调用"use strict";就可以在特定function中使用严格模式"use strict"; 在那些顶部,但有没有办法实现相反?

不,您不能禁用每个function的严格模式。

严格模式在词汇上起作用是很重要的。 含义 – 它影响函数声明,而不是执行。 严格代码中声明的任何函数本身都是严格的函数。 但是从严格的代码中调用的任何函数都不一定是严格的:

 (function(sloppy) { "use strict"; function strict() { // this function is strict, as it is _declared_ within strict code } strict(); sloppy(); })(sloppy); function sloppy(){ // this function is not strict as it is _declared outside_ of strict code } 

请注意,我们可以在严格代码之外定义函数,然后将其传递给严格的函数。

你可以在你的例子中做类似的事情 – 让对象具有“马虎”function,然后将该对象传递给那个严格的立即调用的函数。 当然,如果“马虎”函数需要引用主包装函数中的variables,那么这将不起作用。

另外请注意, 间接eval – 由其他人build议 – 在这里不会真的有帮助。 它所做的就是在全局上下文中执行代码。 如果您尝试调用本地定义的函数,则间接评估甚至不会find它:

 (function(){ "use strict"; function whichDoesSomethingNaughty(){ /* ... */ } // ReferenceError as function is not globally accessible // and indirect eval obviously tries to "find" it in global scope (1,eval)('whichDoesSomethingNaughty')(); })(); 

这个关于全局eval的混淆可能来自全局eval可以用来从严格模式(这不是简单地通过this可以访问)访问全局对象的事实:

 (function(){ "use strict"; this; // undefined (1,eval)('this'); // global object })(); 

但回到问题…

你可以通过Function构造函数来作弊,并声明一个新的函数 – 它不会inheritance严格性,但是依赖(非标准)函数反编译,你将失去引用外部variables的能力

 (function(){ "use strict"; function strict(){ /* ... */ } // compile new function from the string representation of another one var sneaky = Function('return (' + strict + ')()'); sneaky(); })(); 

请注意,FF4 +似乎不符合spec(从我可以告诉),并不正确地标记函数创build的Function严格。 在其他严格模式支持的实现 (如Chrome 12 +,IE10,WebKit)中,这种情况不会发生。

(来自http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/

(…)对严格函数体内调用的非严格函数(或者因为它们是作为parameter passing的,或者是使用callapply调用的),严格模式不会被强制执行。

因此,如果您在不使用严格模式的情况下将错误方法设置为其他文件,然后将它们作为parameter passing,如下所示:

 var test = function(fn) { 'use strict'; fn(); } var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; //will throw TypeError in Strict Mode } test(deleteNonConfigurable); //no error (Strict Mode not enforced) 

它应该工作。

另一种方法就是这样做

 var stack; if (console && console.trace) { stack = console.trace(); } else { try { var fail = 1 / 0; } catch (e) { if (e.stack) { stack = e.stack; } else if (e.stacktrace) { stack = e.stacktrace; } } } // have fun implementing normalize. return normalize(stack);