我在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
是一个不可删除的道具,在检索时抛出。所以我的问题是,是否有人知道禁用严格更多“功能明智”的方式?
"use strict";
。现在我们可以通过在这些函数的顶部调用"use strict";
来在特定函数中使用严格模式,但有没有办法实现相反的目标呢?
答案 0 :(得分:76)
不,您无法为每个功能禁用严格模式。
了解严格模式词汇非常重要;意义 - 它影响函数声明,而不是执行。在严格代码中任何声明的函数本身就成为一个严格的函数。但是,严格代码中的任何称为的函数都不一定严格:
(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
}
注意我们如何在严格代码之外定义函数,然后将其传递给严格的函数。
你可以在你的例子中做类似的事情 - 让一个对象具有“草率”函数,然后将该对象传递给严格的立即调用函数。当然,如果“草率”函数需要从主包装函数中引用变量,那么这将不起作用。
另请注意,indirect eval - 由其他人建议 - 在这里不会真正有用。它所做的只是在全局上下文中执行代码。如果你试图调用一个在本地定义的函数,间接eval甚至都找不到它:
(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')();
})();
关于全局评估的这种混淆可能来自这样一个事实,即全局评估可用于从严格模式(不再可通过this
访问)访问全局对象:
(function(){
"use strict";
this; // undefined
(1,eval)('this'); // global object
})();
但回到问题......
你可以通过Function
构造函数来欺骗并声明一个新函数 - 这恰好是不继承严格性,但这将依赖于(非标准)函数反编译而你会无法引用外部变量。
(function(){
"use strict";
function strict(){ /* ... */ }
// compile new function from the string representation of another one
var sneaky = Function('return (' + strict + ')()');
sneaky();
})();
请注意,FF4 +似乎不同意规范(我可以告诉)并错误地将通过Function
创建的函数标记为严格。其他strict-mode-supporting implementations(例如Chrome 12 +,IE10,WebKit)不会发生这种情况。
答案 1 :(得分:3)
(来自http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/)
(...)未强制执行严格模式 调用的非严格函数 在一个严格的功能体内 (因为他们被传递为 参数或使用
call
或apply
)。
因此,如果您在不使用严格模式的情况下在其他文件中设置错误方法,然后将它们作为参数传递,如下所示:
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)
......它应该有用。
答案 2 :(得分:2)
另一种选择就是这样做
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);