How is JavaScript's strict mode implemented

一世执手 提交于 2019-12-12 06:29:12

问题


Update:

Perhaps the way the function is called is to blame, so here's to it:

2 JS files
  Main.js: self invoking (non-strict) function that adds an event listener for the '(on)load' event.
The callback calls a loader function, that parses the location.pathname, and calls an init function, and detaches/removes the '(on)load' listener & returns null (explicitly).

  PageSpecific.js: contains the _init function, adds a couple of event listeners to the body.
One of these listeners' callback (also returned from a closure) calls the strict function that uses argument.callee as a reference for recursion.
The closure that returns the event handler may -depending on the browser- or may not bind and unbind other events, but I think that's irrelevant here, as this is to imitate an onchange event in IE <9

I hope this is reasonably clear, so its:
anon. F => eventlistener
             => handler (named but declared in anon F) => pageloader =>
                  init => eventListener
                  binding function returned by closure
                      => calls strict function

Incidentally: Here's a trimmed down version of the _init function that is called, that I'm actually using. More specifically: the closure that binds the event Listener and - handler together. Its another one of my length questions, to which nobody seems to know the answer... hint ;-)


I'm debugging some fairly large (and complex) JavaScripts. In doing this, I noticed that I have a function, using strict mode that works fine but should, if I'm not mistaken, throw errors. Since the scripts are fairly sizeable and complex (event delegation, stacked closures etc), here's a simple example:

function withCalleeRecursion(foo)
{
    'use strict';//strict throws typeError on arguments.callee
    foo = foo.replace(/(a|b)+/gi, function (p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,arguments.callee);//no errors
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
    return foo;
}

(function()
{//not strict
    alert(withCalleeRecursion('Abba makes me barf'));
})();

In my actual script, this works perfectly fine. When I pasted this both in Firebug and chrome console, an error is thrown, though. I've tried this code here, so IE should throw errors, too, but when I run the code in IE's debugger, it works just fine. As far as I can work out, changing the doctype (tried html5 and html4) makes no difference.

Am I right in thinking that (most) browsers aren't as strict with the 'use strict'; directive as it's name suggests? It would seem that the browsers choose to ignore it when a possible error is detected when parsing the script. Is this true?


Meanwhile, I have made a slight change to the function, just out of precaution. Since I've seen quite a few questions here of people wondering how to get the callee reference in strict mode, I'm pasting it here, too:

function withCalleeRecursion(foo)
{
    'use strict';
    foo = foo.replace(/(a|b)+/gi, function abR(p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,abR);
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
    return foo;
}

Name the callback, that's all.


回答1:


It's probably because browser consoles use eval(), which changes things. Although putting "use strict"; at the start of a string of code that is passed to eval() works as expected, it's possible that console implementations prepend code to the string you've typed into the console, meaning that "use strict"; is no longer the first statement executed and is therefore ignored.

There's a reference to this and a suggested workaround in the following article:

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

The suggested workaround is to wrap code in the console within a function that is immediately executed:

(function() {
    "use strict";
    nonExistentVariable = 1; // Error is now thrown
})();



回答2:


Maybe this article can help you to understand more. Anyway the solution is the one you mention, the error is because access to arguments.caller and arguments.callee throw an exception in strict mode. Thus any anonymous functions that you want to reference will need to be named.



来源:https://stackoverflow.com/questions/11345367/how-is-javascripts-strict-mode-implemented

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!