我可以为特定功能禁用ECMAscript严格模式吗?
-
14-11-2019 - |
题
我在MDC或ECMAscript规范中没有找到任何关于我的问题的信息。也许有人知道一个更"hacky"的方法来解决这个问题。
我在打电话 "use strict"
在我的环境中的每个javascript文件上。我所有的文件都是这样开始的
(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";
在那些顶部,但有没有办法实现相反的?
解决方案
不,您不能为每个函数禁用严格模式。
重要的是要了解严格模式的工作原理 词汇学;含义-它影响函数声明,而不是执行。任何功能 声明 在严格的代码中成为一个严格的函数本身。但不是任何功能 被称为 从严格的代码必然是严格的:
(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甚至找不到它:
(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
构造函数-发生在 不继承 严格,但这将依赖于(非标准)函数反编译,你会 失去引用外部变量的能力.
(function(){
"use strict";
function strict(){ /* ... */ }
// compile new function from the string representation of another one
var sneaky = Function('return (' + strict + ')()');
sneaky();
})();
请注意,FF4+似乎不同意spec(从我可以告诉),并错误地标记通过创建的函数 Function
一样严格。这不会发生在其他 支持严格模式的实现 (如Chrome12+,IE10,WebKit)。
其他提示
(从 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)
..。它应该工作。
另一种选择就是这样做
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);