我可以为特定功能禁用 ECMAscript 严格模式吗?

发布于 2024-11-08 02:10:47 字数 832 浏览 6 评论 0原文

我在 MDC 或 ECMAscript 规范上找不到任何有关我的问题的信息。可能有人知道一种更“hacky”的方法来解决这个问题。

我正在对我的环境中的每个 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 是一个不可删除的 prop,在检索时会抛出异常。所以我的问题是,有人知道如何禁用更严格的“功能方面”吗?

"use strict"; 在调用后被所有函数继承。现在我们可以通过在这些函数的顶部调用 "use strict"; 来在特定函数中使用严格模式,但是有没有办法实现相反的效果呢?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疧_╮線 2024-11-15 02:10:47

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

重要的是要理解严格模式在词法上上起作用;意思是——它影响函数声明,而不是执行。严格代码中声明的任何函数本身都会成为严格函数。但并非任何从严格代码中调用的函数都一定是严格的:

(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
}

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

您可以在示例中执行类似的操作 - 拥有一个具有“草率”函数的对象,然后将该对象传递给该严格的立即调用函数。当然,如果“草率”函数需要引用主包装函数中的变量,那么这将不起作用。

另请注意,间接评估(由其他人建议)获胜在这里真的没有帮助。它所做的只是在全局上下文中执行代码。如果您尝试调用本地定义的函数,间接 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+ 似乎不符合规范(据我所知),并且错误地将通过 Function 创建的函数标记为严格。在其他严格模式支持实现(例如 Chrome 12+)中不会发生这种情况、IE10、WebKit)。

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).

饭团 2024-11-15 02:10:47

(来自 http://javascriptweblog.wordpress.com/2011/05/ 03/javascript-严格模式/)

(...) 不强制执行严格模式
调用的非严格函数
在严格函数体内
(或者因为它们被传递为
参数或使用 call 调用或
申请)。

因此,如果您在不同的文件中设置错误方法,而不使用严格模式,然后将它们作为参数传递,如下所示:

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)

...它应该可以工作。

(From http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/)

(...) Strict Mode is not enforced on
non-strict functions that are invoked
inside the body of a strict function
(either because they were passed as
arguments or invoked using call or
apply).

So if you setup the error methods in a different file, without strict mode, and then pass them as a parameter, like this:

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)

...it should work.

冬天旳寂寞 2024-11-15 02:10:47

另一种选择就是简单地这样做

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);

An alternative is simply doing this

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文