我可以为特定功能禁用ECMAscript严格模式吗? [英] Can I disable ECMAscript strict mode for specific functions?

查看:160
本文介绍了我可以为特定功能禁用ECMAscript严格模式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MDC或ECMAscript规范中没有找到关于我的问题的任何内容。可能有人知道一种更笨拙的方法来解决这个问题。



我打电话给use strict on我环境中的每个javascript文件。我的所有文件都是这样开始的

 (函数(win,doc,undef){
use strict;

//代码和函数
}(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; ,但有没有办法实现相反的目的?

解决方案

不,你不能为每个功能禁用严格模式。



了解严格模式词汇非常重要意义 - 它影响函数声明,而不是执行。在严格代码中任何声明的函数本身就成为一个严格的函数。但严格代码中的任何名称都不一定严格:

 (function(sloppy){ 
use strict;

function strict(){
//这个函数是严格的,因为它是严格代码中的_declared_
}

strict();
sloppy();

})(草率);

函数sloppy(){
//此函数不严格,因为它是_declared outside_ of strict code
}

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



你可以在你的例子中做类似的事情 - 拥有一个带有草率函数的对象,然后将该对象传递给严格的立即调用函数。当然,如果草率函数需要从主包装函数中引用变量,那将无效。



另请注意间接评估 - 由其他人建议 - 在这里不会真正有用。它所做的只是在全局上下文中执行代码。如果你试图调用一个在本地定义的函数,间接eval甚至都找不到它:

 (function(){
use strict;

函数whichDoesSomethingNaughty(){/ * ... * /}

//函数的ReferenceError不可全局访问
//和间接eval显然试图在全局范围内找到它
(1,eval)('whichDoesSomethingNaughty')();

})();

关于全局评估的这种混淆可能来自全球评估可用于访问全局的事实严格模式内的对象(不能简单地通过进行访问):

 (function(){
use strict;

this; // undefined
(1,eval)('this'); //全局对象
})();

但回到问题......



<你可以通过函数构造函数来欺骗和声明一个新函数 - 这恰好是不继承严格性,但这依赖于(非 - 标准)函数反编译你会失去引用外部变量的能力

 (function() {
use strict;

function strict(){/ * ... * /}

//从另一个字符串表示编译新函数一个
var sneaky =函数('return('+ strict +')()');

sneaky();
})();

请注意,FF4 +似乎不同意规范(我可以告诉)并错误地标记通过功能严格。在其他严格模式支持实施(如Chrome 12+)中不会发生这种情况,IE10,WebKit)。


I don't find anything about my question here on MDC or the ECMAscript specifications. Probably somebody knows a more 'hacky' way to solve this.

I'm calling "use strict" on every javascript file in my environment. All my files start like this

(function(win, doc, undef) {
    "use strict";

    // code & functions
}(window, window.document));

Now, I have a custom function which handles errors. That functions uses the .caller property to provide a context stack trace. Looks like this:

var chain = (function() {
    var _parent = _error,
        _ret = '';

    while( _parent.caller ) {
        _ret += ' -> ' + _parent.caller.name;
        _parent = _parent.caller;
    }

    return _ret;
}());

But of course, in strict mode .caller is a non-deletable prop which throws when retrieved. So my question is, is anybody aware of way to disable strict more "function-wise" ?

"use strict"; is inherited by all functions after it was called. Now we have the possibilty to just use strict mode in specific functions by just calling "use strict"; at the top of those, but is there a way to achieve the opposite ?

解决方案

No, you can't disable strict mode per function.

It's important to understand that strict mode works lexically; meaning — it affects function declaration, not execution. Any function declared within strict code becomes a strict function itself. But not any function called from within strict code is necessarily 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
}

Notice how we can define function outside of strict code and then pass it into the function that's strict.

You can do something similar in your example — have an object with "sloppy" functions, then pass that object to that strict immediately invoked function. Of course, that won't work if "sloppy" functions need to reference variables from within main wrapper function.

Also note that indirect eval — suggested by someone else — won't really help here. All it does is execute code in global context. If you try to call a function that's defined locally, indirect eval won't even find it:

(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 confusion about global eval probably comes from the fact that global eval can be used to get access to global object from within strict mode (which isn't simply accessible via this anymore):

(function(){
  "use strict";

  this; // undefined
  (1,eval)('this'); // global object
})();

But back to the question...

You can kind of cheat and declare a new function via Function constructor — which happens to not inherit strictness, but that would rely on (non-standard) function decompilation and you would lose ability to reference outer variables.

(function(){
  "use strict";

  function strict(){ /* ... */ }

  // compile new function from the string representation of another one
  var sneaky = Function('return (' + strict + ')()');

  sneaky();
})();

Note that FF4+ seems to disagree with spec (from what I can tell) and incorrectly marks function created via Function as strict. This doesn't happen in other strict-mode-supporting implementations (like Chrome 12+, IE10, WebKit).

这篇关于我可以为特定功能禁用ECMAscript严格模式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆