2013-02-28 70 views
6

中测试了一些js代码Chrome开发者控制台,我有点困惑。JavaScript'严格使用';里面的函数

我知道,在严格模式函数时提到不属于某个对象的方法这关键字应该得到不确定,而不是全局对象。

function test(){ 
    "use strict"; 
    return this===undefined;} 
test(); 

输出false

"use strict"; 
function test(){ 
    return this===undefined;} 
test(); 

仍然false

(function test(){ 
    "use strict"; 
    return this===undefined;}()); 

输出真正

只是想澄清。 'm•ᴥ•ʔ我是js的新手。

+2

请阅读类似的问题http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it – hexblot 2013-02-28 12:20:40

+4

@hexblot这并不回答这个问题,虽然...... – Christoph 2013-02-28 12:37:00

回答

2

它是Chromium开发人员控制台中的一个错误,它会导致this仍引用全局对象。相同的代码在位置栏和文档中的作用与javascript:中指定的相同。

可以测试像这样(2控制台输入):

var global = (function() { return this; }()); 

"use strict"; 
function test() { return this === global; } 
test(); 

和(一个或多个控制台输入)

var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.appendChild(document.createTextNode(
    'function test() { "use strict"; return this === undefined; }; console.log(test());' 
)); 
document.body.appendChild(script); 

测试在铬版25.0.1364.97的Debian 7.0(183676) 。

+0

你的第一个测试是一个破碎的测试。即使你在脚本标记而不是控制台中运行它,你仍然会得到'true',因为''use strict''必须是它的作用域中的* first *行。你的例子在'var global ...'之后出现,所以该指令被忽略(按照规范)。 – 2013-03-02 01:52:46

+0

@NathanWall不,请参阅我的说明。我建议你在函数中使用'debugger;'来检查调用堆栈。 – PointedEars 2013-03-03 12:27:53

2

一切都很好。如果您通过某个HTML页面(而不是开发控制台)运行代码,则结果符合预期(始终为this===undefined)。

此外,在最新的Firefox(萤火虫):

function test(){ 
    "use strict"; 
    return this===undefined;} 
test(); 
>> true 

因此,这似乎只是一个浏览器的bug(功能?)。感觉就像它通过dev控制台传递的代码有一个稍微不同的方法。

另外请注意,为了事项:

<script> 
    console.log('Me First!'); 

    "use strict"; 

    function test(){ 
     console.log(this); 
    } 
    test(); 

</script> 

>>> "Me First!" 
>>> Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…} 

但是:

<script> 
    "use strict"; 

    console.log('Me later!'); 

    function test(){ 
     console.log(this); 
    } 
    test(); 

</script> 

>>> undefined 
>>> "Me later!" 
4

什么,你已经注意到了根本的办法副作用的开发者控制台的作品。当你在那里输入代码,这实际上是发生了什么(见this answer有详细介绍):

eval.call(null, "with (window) { \ 
        function test() { \ 
         'use strict'; \ 
         console.log(this); \ 
        } test(); \ 
       }"); 

这是一个间接呼叫eval,这意味着它会一直在全球执行上下文中执行(在浏览器,这是window)。

实际上,该功能被绑定到全局对象,因此this持有全局对象的引用,因为如果你在网页中(而不是在控制台)这样做:

function test(){ 
    "use strict"; 
    return this === undefined; 
} 

test(); // true 
test.call(window); // false 
+1

像'window' *引用的对象是* *不是执行上下文。执行上下文是一个抽象程序实体;它有一个*范围链*,其中有对象。在这种情况下,它将是'with'语句,用于'test()'调用上下文的范围链中插入'window'引用的对象。 – PointedEars 2013-02-28 12:58:30

+0

@PointedEars - 当然可以。我本可以说“窗口对象所属的词汇环境的环境记录”,但我认为它的方式更简单,我认为它仍然是重中之重。而'with'语句在这种情况下没有什么区别 - 这就是'eval'被调用的方式,它会影响其参数被评估的上下文。 – 2013-02-28 13:11:48

+0

这里的'with'语句*可能很重要;当然,如果你认为(IMO错误地)全局对象的'window'主机属性总是引用全局对象。因为那么'test()'调用将等同于'global.window.test()',其中'global'将作为全局对象的标准引用的替身。 – PointedEars 2013-03-01 00:52:48