Firefox 4 中的 ECMAScript 5 严格模式

编辑注:本文由 Chris Heilmann 发布,但作者是 Jeff Walden - 应归功于应得的人。

Mozilla 社区的开发者对 Firefox 4 中的 JavaScript 引擎进行了重大改进。我们投入了大量精力来提高性能,但也致力于开发新功能。我们尤其关注 ECMAScript 5,这是 JavaScript 底层标准的最新更新。

严格模式可以说是 ECMAScript 5 中最有趣的新功能。它是一种选择加入 JavaScript 受限变体的模式。严格模式不仅仅是一个子集:它有意与普通代码具有不同的语义。不支持严格模式的浏览器会以与支持严格模式的浏览器不同的方式运行严格模式代码,因此不要依赖严格模式,而无需对严格模式的相关方面进行功能测试。

严格模式代码和非严格模式代码可以共存,因此脚本可以逐步选择加入严格模式。严格模式为未来 ECMAScript 版本铺平了道路,在未来版本中,使用特定 <script type="..."> 的新代码可能会自动以严格模式执行。

严格模式有什么作用?首先,它消除了 JavaScript 中一些不会导致错误的缺陷,将其更改为产生错误。其次,它修复了一些错误,这些错误使得 JavaScript 引擎难以执行优化:严格模式代码有时可以比相同的非严格模式代码运行得更快。Firefox 4 通常还没有优化严格模式,但后续版本将进行优化。第三,它禁止了一些可能在未来 ECMAScript 版本中定义的语法。

调用严格模式

严格模式适用于整个脚本单个函数。它不适用于用 {} 大括号括起来的块语句;尝试将其应用于此类上下文不会有任何效果。eval 代码、事件处理程序属性、传递给 setTimeout 的字符串等等都是完整的脚本,在其中调用严格模式可以按预期工作。

脚本的严格模式

要为整个脚本调用严格模式,请在任何其他语句之前放置精确语句 "use strict";(或 'use strict';)。

// Whole-script strict mode syntax
"use strict";
var v = "Hi!  I'm a strict mode script!";

此语法有一个陷阱,该陷阱已经困扰 一个主要网站:无法盲目地连接不冲突的脚本。考虑将严格模式脚本与非严格模式脚本连接:整个连接看起来很严格!反之亦然:非严格模式加上严格模式看起来是非严格模式。严格模式脚本之间的连接是可以的,非严格模式脚本之间的连接也是可以的。只有交叉流通过连接严格模式和非严格模式脚本,才会出现问题。

函数的严格模式

同样,要为函数调用严格模式,请在函数体内的任何其他语句之前放置精确语句 "use strict";(或 'use strict';)。

function strict()
{
  // Function-level strict mode syntax
  'use strict';
  function nested() { return "And so am I!"; }
  return "Hi!  I'm a strict mode function!  " + nested();
}
function notStrict() { return "I'm not strict."; }

严格模式中的更改

严格模式更改了语法和运行时行为。更改通常分为以下几类

  • 将错误转换为错误(作为语法错误或在运行时)
  • 简化计算特定变量对给定名称的使用方式
  • 简化 evalarguments
  • 使编写“安全”JavaScript 更容易
  • 预测未来的 ECMAScript 演变

将错误转换为错误

严格模式将一些先前接受的错误更改为错误。JavaScript 的设计初衷是为了让新手开发者易于使用,因此有时它会对应该导致错误的操作提供非错误语义。有时这会修复直接问题,但有时会导致将来出现更严重的问题。严格模式将这些错误视为错误,以便发现并及时修复。

首先,严格模式使得意外创建全局变量成为不可能。在普通 JavaScript 中,在赋值中误写变量会在全局对象上创建一个新属性,并继续“工作”(尽管将来可能会失败:在现代 JavaScript 中,这很可能)。在严格模式中,意外创建全局变量的赋值会抛出错误

"use strict";
mistypedVaraible = 17; // throws a ReferenceError

其次,严格模式使得会静默失败的赋值抛出异常。例如,NaN 是一个不可写的全局变量。在普通代码中,对 NaN 赋值不会有任何效果;开发者不会收到任何失败反馈。在严格模式中,对 NaN 赋值会抛出异常。任何在普通代码中静默失败的赋值都会在严格模式中抛出错误

"use strict";
NaN = 42; // throws a TypeError
var obj = { get x() { return 17; } };
obj.x = 5; // throws a TypeError
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // throws a TypeError

第三,如果您尝试删除不可删除的属性,严格模式会抛出错误(之前,此尝试只是没有效果)

"use strict";
delete Object.prototype; // throws a TypeError

第四,严格模式要求对象文字中命名的所有属性都是唯一的。普通代码可能会重复属性名称,最后一个属性名称决定属性的值。但由于只有最后一个属性名称起作用,因此重复只是错误的载体,如果代码被修改以更改属性值(而不是更改最后一个实例),就会发生这种情况。在严格模式中,重复的属性名称是语法错误

"use strict";
var o = { p: 1, p: 2 }; // !!! syntax error

第五,严格模式要求函数参数名称是唯一的。在普通代码中,最后一个重复的参数会隐藏先前具有相同名称的参数。这些先前的参数仍然可以通过 arguments[i] 访问,因此它们并非完全无法访问。尽管如此,这种隐藏意义不大,可能也不理想(例如,它可能会隐藏错别字),因此在严格模式中,重复的参数名称是语法错误

function sum(a, a, c) // !!! syntax error
{
  "use strict";
  return a + b + c; // wrong if this code ran
}

第六,严格模式禁止八进制语法。八进制语法不是 ECMAScript 的一部分,但它在所有浏览器中都支持,方法是在八进制数前面加上一个零:0644 === 420"\045" === "%"。新手开发者有时会认为,以零开头的前缀没有语义意义,因此他们将其用作对齐设备 - 但这会改变数字的含义!八进制语法很少有用,可能会被误用,因此严格模式将八进制语法视为语法错误

"use strict";
var sum = 015 + // !!! syntax error
          197 +
          142;

简化变量使用

严格模式简化了变量使用与代码中特定变量定义之间的映射方式。许多编译器优化依赖于能够说这个变量存储在这个位置的能力:这对于完全优化 JavaScript 代码至关重要。JavaScript 有时会使得这种基本名称到代码中变量定义的映射无法在运行时以外执行。严格模式消除了大多数发生这种情况的情况,因此编译器可以更好地优化严格模式代码。

首先,严格模式禁止使用 withwith 的问题在于,其中的任何名称都可能在运行时映射到传递给它的对象的属性,或者映射到周围代码中的变量:无法事先知道。严格模式将 with 视为语法错误,因此 with 中的名称不可能在运行时引用未知位置

"use strict";
var x = 17;
with (obj) // !!! syntax error
{
  // If this weren't strict mode, would this be var x, or
  // would it instead be obj.x?  It's impossible in general
  // to say without running the code, so the name can't be
  // optimized.
  x;
}

将对象赋值给一个变量,然后访问该变量上的相应属性,这种简单的替代方案可以用来代替 with

其次,在严格模式代码中使用 eval 不会向周围代码中引入新变量。在普通代码中,eval("var x;") 会向周围函数或全局范围引入一个变量 x。这意味着,一般来说,在一个包含对 eval 的调用的函数中,每个不引用参数或局部变量的名称都必须在运行时映射到一个特定的定义(因为该 eval 可能引入了一个新的变量,该变量会隐藏外部变量)。在严格模式中,eval 只为要评估的代码创建变量,因此 eval 不会影响名称是引用外部变量还是一些局部变量。

var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
assert(x === 17);
assert(evalX === 42);

相关地,如果函数 eval 是通过严格模式代码中 eval(...) 形式的表达式调用的,那么该代码将作为严格模式代码进行评估。该代码可以显式调用严格模式,但这样做是不必要的。

function strict1(str)
{
  "use strict";
  return eval(str); // str will be treated as strict mode code
}
function strict2(f, str)
{
  "use strict";
  return f(str); // not eval(...): str is strict iff it invokes strict mode
}
function nonstrict(str)
{
  return eval(str); // str is strict iff it invokes strict mode
}
strict1("'Strict mode code!'");
strict1("'use strict'; 'Strict mode code!'");
strict2(eval, "'Non-strict code.'");
strict2(eval, "'use strict'; 'Strict mode code!'");
nonstrict("'Non-strict code.'");
nonstrict("'use strict'; 'Strict mode code!'");

第三,严格模式禁止删除普通名称。因此,严格模式 eval 代码中的名称的行为与没有作为 eval 结果进行评估的严格模式代码中的名称相同。在严格模式中使用 delete name 是语法错误

"use strict";
eval("var x; delete x;"); // !!! syntax error

使 evalarguments 更简单

严格模式使得 argumentseval 变得不那么神奇了。在普通代码中,两者都涉及大量的魔幻行为:eval 添加或删除绑定,并更改绑定值,arguments 通过其索引属性对命名参数进行别名。严格模式在将 evalarguments 视为关键字方面取得了很大进展,尽管完整的修复要等到 ECMAScript 的未来版本。

首先,名称 evalarguments 不能在语言语法中被绑定或赋值。所有这些尝试都是语法错误

"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");

其次,严格模式代码不会对在其中创建的 arguments 对象的属性进行别名。在普通代码中,在一个第一个参数为 arg 的函数内,设置 arg 也会设置 arguments[0],反之亦然(除非没有提供任何参数或 arguments[0] 被删除)。对于严格模式函数,arguments 对象存储函数被调用时的原始参数。arguments[i] 的值不会跟踪相应命名参数的值,反之亦然。

function f(a)
{
  "use strict";
  a = 42;
  return [a, arguments[0]];
}
var pair = f(17);
assert(pair[0] === 42);
assert(pair[1] === 17);

第三,arguments.callee不再被支持。在普通代码中,arguments.callee引用的是封闭函数。这种用例很弱:只需命名封闭函数即可!此外,arguments.callee严重阻碍了诸如内联函数之类的优化,因为如果访问arguments.callee,就必须能够提供对未内联函数的引用。对于严格模式函数,arguments.callee是一个不可删除的属性,在设置或检索时会抛出错误。

"use strict";
var f = function() { return arguments.callee; };
f(); // throws a TypeError

“保护”JavaScript

严格模式使编写“安全”JavaScript变得更容易。一些网站现在为用户提供了一种方式,让他们编写将在网站上运行的JavaScript,代表其他用户。浏览器中的JavaScript可以访问用户的私有信息,因此此类JavaScript必须在运行之前进行部分转换,以屏蔽对禁止功能的访问。JavaScript的灵活性使得在没有许多运行时检查的情况下,有效地做到这一点是不可能的。某些语言功能非常普遍,以至于执行运行时检查会产生相当大的性能成本。一些严格模式调整,加上要求用户提交的JavaScript是严格模式代码,并且以某种方式调用,大大减少了对这些运行时检查的需求。

首先,在严格模式下作为this传递给函数的值不会被封装到对象中。对于普通函数,this始终是一个对象:如果使用对象值的this调用,则为提供的对象;如果使用布尔值、字符串或数字this调用,则为该值(被封装);或者如果使用undefinednullthis调用,则为全局对象。(使用callapplybind来指定特定的this。)自动封装是一个性能成本,但在浏览器中暴露全局对象是一个安全隐患,因为全局对象提供了对“安全”JavaScript环境必须始终具有的功能的访问权限。因此,对于严格模式函数,指定的this将保持不变。

"use strict";
function fun() { return this; }
assert(fun() === undefined);
assert(fun.call(2) === 2);
assert(fun.apply(null) === null);
assert(fun.call(undefined) === undefined);
assert(fun.bind(true)() === true);

(与主题相关的是,如果thisnullundefined,内置方法现在也不会将this封装到对象中。[此更改与严格模式无关,但出于对暴露全局对象的相同担忧而导致的。]历史上,将nullundefined传递给像Array.prototype.sort()这样的内置方法,就像指定了全局对象一样。现在,将这两个值中的任何一个作为this传递给大多数内置方法都会抛出TypeError。布尔值、数字和字符串仍然会被这些方法封装:只有在这些方法原本会对全局对象进行操作时,它们才被更改。)

其次,在严格模式下,无法通过通常实现的ECMAScript扩展来“遍历”JavaScript堆栈。在使用这些扩展的普通代码中,当一个函数fun正在被调用时,fun.caller是最近调用fun的函数,而fun.arguments是该fun调用的arguments。这两个扩展对于“安全”JavaScript来说都有问题,因为它们允许“安全”代码访问“特权”函数及其(可能不安全)参数。如果fun是严格模式的,那么fun.callerfun.arguments都是不可删除的属性,在设置或检索时会抛出错误。

function restricted()
{
  "use strict";
  restricted.caller;    // throws a TypeError
  restricted.arguments; // throws a TypeError
}
function privilegedInvoker()
{
  return restricted();
}
privilegedInvoker();

第三,严格模式函数的arguments不再提供对相应函数调用的变量的访问权限。在一些旧的ECMAScript实现中,arguments.caller是一个对象,其属性是该函数中变量的别名。这是一个安全隐患,因为它破坏了通过函数抽象隐藏特权值的能力;它也排除了大多数优化。由于这些原因,最近的浏览器都没有实现它。然而,由于其历史功能,严格模式函数的arguments.caller也是一个不可删除的属性,在设置或检索时会抛出错误。

"use strict";
function fun(a, b)
{
  "use strict";
  var v = 12;
  return arguments.caller; // throws a TypeError
}
fun(1, 2); // doesn't expose v (or a or b)

为未来ECMAScript版本铺平道路

未来的ECMAScript版本可能会引入新的语法,而ECMAScript 5中的严格模式应用了一些限制,以简化过渡。如果严格模式禁止这些更改的基础,那么进行某些更改将更容易。

首先,在严格模式下,一小部分标识符将变成保留关键字。这些词是implementsinterfaceletpackageprivateprotectedpublicstaticyield。那么,在严格模式下,就不能使用这些名称来命名或使用变量或参数。Mozilla特有的注意事项:如果你的代码是JavaScript 1.7或更高版本(你是chrome代码,或者你使用了正确的<script type="">),并且是严格模式代码,那么letyield将具有自这些关键字首次引入以来的功能。但是,在网络上加载的严格模式代码,使用<script src=""><script>...</script>,将无法使用let/yield作为标识符。

其次,严格模式禁止不在脚本或函数顶层的函数语句。在浏览器中的普通代码中,函数语句在“任何地方”都是允许的。这不是ES5的一部分!它是一个扩展,在不同的浏览器中具有不兼容的语义。未来的ECMAScript版本希望为不在脚本或函数顶层的函数语句指定新的语义。在严格模式下禁止此类函数语句为在未来的ECMAScript版本中进行规范“扫清障碍”。

"use strict";
if (true)
{
  function f() { } // !!! syntax error
  f();
}
for (var i = 0; i < 5; i++)
{
  function f2() { } // !!! syntax error
  f2();
}
function baz() // kosher
{
  function eit() { } // also kosher
}

这种禁止不是严格模式本身,因为此类函数语句是一个扩展。但这是ECMAScript委员会的建议,浏览器将实现它。

浏览器中的严格模式

Firefox 4是第一个完全实现严格模式的浏览器。许多WebKit浏览器中使用的Nitro引擎也不甘落后,几乎完全支持严格模式。Chrome也开始实现严格模式。Internet Explorer和Opera尚未开始实现严格模式;请随时向这些浏览器制造商发送反馈,要求他们支持严格模式。

浏览器不稳定地实现严格模式,因此不要盲目依赖它。严格模式改变了语义。依赖这些更改会导致在不实现严格模式的浏览器中出现错误和错误。在使用严格模式时要谨慎,并通过功能测试来支持对严格模式的依赖,以检查严格模式的相关功能是否已实现。

要测试严格模式,请下载Firefox nightly并开始使用。在编写新代码和更新现有代码时,也要考虑它的限制。(但是,为了绝对安全,最好等到它在浏览器中发布后才将其用于生产环境。)

关于 Chris Heilmann

HTML5和开放网络的布道者。让我们解决这个问题!

更多来自Chris Heilmann的文章…


26条评论

  1. JulienW

    感谢Mozilla,这真是太好了。现在让我们在开发过程中使用“use strict”,并在发布后将其删除,直到它发布并且我们确定它没有错误为止。或者不用,我们现在就用它。

    这会进入下一个测试版吗?我不明白测试版是直接来自主干还是Firefox 4已经有了自己的分支(尽管看起来不像这样)。

    2011年1月25日下午08:55

    1. Jeff Walden

      它将在下一个测试版中发布。严格模式的许多部分也包含在之前的测试版中;eval变量绑定更改是我们完成实现之前正在进行的最后一个重要部分,之后我们才愿意说严格模式“完成了”。(“完成”是因为错误仍然存在,并且从某种意义上说,可能永远存在。)

      2011年1月25日下午10:08

  2. Jeff Walden

    “与主题相关的是,如果this为null或undefined,内置方法现在也不会将this封装到对象中。”

    我迟到了,我发现我们还没有实现它:错误619283。我们很快就会解决这个问题,但如果您特别关注“安全”变体功能,请在解决这个问题之前不要依赖它。(并不是说你很有可能现在就开始依赖它!你必须非常超前才能做到这一点。:-))

    2011年1月25日上午09:25

  3. oliver

    JSC的严格模式缺少什么?

    2011年1月25日上午09:49

    1. Jeff Walden

      上次我查看时,kangax的严格模式页面仍然标记了一些细微之处。此外,我提交了错误53014,并在昨天将你CC到邮件中,这是我写这篇帖子之前几乎忘记的最后一件事(我们特意在今天的夜间构建完成后立即发布这篇帖子,以便将该更改纳入其中)。除了这些细节之外,我认为你已经设置好了,至少就功能而言(除了我在几周前在IRC中提到的eval测试等错误之外)。但我承认我没有密切关注Nitro的开发,所以我的判断主要基于他人的评估以及少量我自己的测试。

      2011年1月25日下午10:06

  4. Weaner

    “function f() { }”不总是和“var f = function () {}”一样吗?我记得道格拉斯·克罗克福德在其中一个视频中说过这句话。这意味着后者在这种情况下也被禁止了吗?

    2011年1月25日下午10:32

    1. Jeff Walden

      它们并不相同。在ECMAScript指定行为的两个情况下,函数语句是在该作用域(无论是程序还是函数)中的任何代码执行之前处理的。因此,这个例子可以在不抛出异常的情况下工作。

      var v = g();
      function g() { return "processed before other statements execute"; }
      

      同样对于这个例子

      function f()
      {
        return g();
        function g() { return "processed before other statements"; }
      }
      f();
      

      如果你在这些例子中将var赋值给一个变量,赋值将按照源代码顺序进行,因此这些例子将失败——赋值将在调用函数之后发生,但调用尝试会抛出错误,因为变量将是undefined

      2011年1月25日下午12:38

  5. Philip Jägenstedt

    严格模式是否实现了一些没有它就不可能实现的优化?对于没有实现ECMAScript引擎的人(我)来说,看起来提到的所有优化都可以通过在解析过程中进行一些分析来针对非严格代码进行。在最简单的做法中,在解析过程中检查是否存在任何eval、with、arguments.callee、arguments.caller等实例,如果不存在,则执行你所说的严格模式启用的智能优化。是否存在漏洞会使簿记比优化带来的收益更加昂贵?表面上看起来不太可能,因为簿记与你为了抛出新的语法错误而需要做的工作基本相同。也许神奇的秘诀在于一些新的运行时行为?我遗漏了什么,还是严格模式实际上对于性能来说并不那么有用?

    2011年1月25日下午13:28

    1. Jeff Walden

      这基本上就是 SpiderMonkey 的工作原理,也是其他高质量引擎的做法。但有一些细微之处。

      “一些分析”在很多情况下过于复杂。你不能在分析上花费太多时间,否则所花费的时间会抵消收益。让它足够特别以适应寄存器分配,比如,几乎是不可能的。你可能只能在随后的重新解析中进行优化,但这样你就会得到比看似简单的修复方案更多的智能。我们(和其他浏览器,怪罪 SunSpider 的愚蠢 JS 代码)有时会这样做——如果你在完全相同的位置重新编译完全相同的 `eval` 代码,我们会缓存代码的“脚本”——但实现起来并不像你说的那样容易。它可能也很脆弱。

      实际上,新的运行时行为是大部分可能的收益。如果没有它,你就无法执行大多数 JS 引擎可以执行的优化所依赖的名称优化。你可能能够在某些情况下进行快速路径优化,但这是一个相当复杂的工作。而且,大多数 JS 开发人员都同意严格模式禁止的东西不是好做法(`arguments.callee` 可能是唯一一个可能不符合这种情况的,但主要是因为旧版 IE 的错误导致命名函数表达式无法正常工作)。

      2011 年 1 月 26 日 下午 6:22

    2. Jeff Walden

      更精确地回答:严格模式允许你在存在 `eval` 的情况下优化名称绑定。因此,如果我在严格模式代码中在一个使用 `eval` 的函数内命名一个外部变量,我知道它将始终引用外部变量,而不是 `eval` 引入的绑定。这是当前 JS 引擎放弃的地方——当它们看到 `eval` 时,它们会抛弃所有优化(比如那个)。它们必须这样做:如果没有严格模式语义,`eval` 可能会引入一个隐藏外部名称的局部变量。如果你让 `eval` 遵守严格模式,那么你就可以优化这个名称引用,而以前你无法这样做。

      当然,你可以想象超级聪明的作弊行为,即使在这种情况下也能优化并以某种方式避免被发现,用 Smalltalk 的格言来说。SpiderMonkey 可能会在某个时刻实现一些这样的火箭手术。对我来说,通过“修复”语言来避免这种需求似乎更好。:-)

      我还应该指出,这些严格模式修复的最终目标是让 ES6 在脚本元素上使用 `type=""` 启用更多 opt-in 模式时,不要使用共享全局对象。将严格模式限制应用于整个脚本,并将共享全局对象从画面中移除,所有名称使用到绑定映射都可以在编译时确定,在执行之前。而让你可以在编译时检测并拒绝错误键入和未声明的变量名称。不再需要小心翼翼地将对未声明的全局变量的赋值变成运行时错误,而这种错误只会在运行代码时才会发生!如果你在任何地方犯错,代码就根本无法工作。你无法比这更早地报告错误了。

      2011 年 1 月 28 日 上午 10:44

  6. oxdef

    嗯,语句的语法还不清楚,但语句本身是一个好主意。
    就像 Perl 中一样。

    2011 年 1 月 25 日 下午 2:06

  7. marcoos

    Chris 写了一篇很棒的文章。我把它翻译成了波兰语。:)

    这篇 MozHacks 文章的波兰语翻译 / tej notki polskie tłumaczenie
    http://blog.marcoos.com/2011/01/25/ecmascript-5-strict-mode-tryb-scisly/

    2011 年 1 月 25 日 下午 2:08

  8. Daniel Kirsch

    有没有一种方法可以为所有脚本全局启用严格模式?至少在 Chrome 环境中,用于插件或基于 XULRunner 的应用程序。

    2011 年 1 月 25 日 下午 5:18

    1. Jeff Walden

      目前还没有。我不确定是否值得添加一个;随意提交一个错误。

      2011 年 1 月 25 日 下午 5:30

  9. Steffen

    这与 `javascript.options.strict` 首选项有什么关系?
    这是不同的严格模式吗?

    2011 年 1 月 26 日 上午 1:14

    1. Jeff Walden

      这是一个不同的严格模式。多么棒啊!也许我们应该将我们的模式改名为火鸟模式。想法?

      (……我开玩笑!)

      说真的,这种冲突很不幸,但严格模式是语言特性的正确名称,我们实施了一些与它类似但调用方式完全不同并且在某些情况下具有非常不同行为的东西,这仅仅是我们自己的损失。

      2011 年 1 月 26 日 下午 6:27

  10. Neil Rashbrook

    所有严格模式错误是否都以非严格模式暴露为警告(`javascript.options.strict` 打开的情况下)?

    2011 年 1 月 26 日 上午 4:12

    1. Jeff Walden

      我认为大多数都是,但完整的答案是否定的,因为 `with` 不会触发任何警告。(它曾经触发过,但警告不足以促使开发人员更改他们的代码,因此我们不会再对 `with` 大肆渲染。)

      2011 年 1 月 26 日 上午 9:02

  11. Jethro Larson

    在我看来,严格模式在它真正启用某些功能之前不会得到广泛使用。Web 开发人员只会把它看作新的约束,只会让完成工作变得更加困难。如果严格模式确实更高效或包含让你编写更多、更快代码的功能,那么它的采用率可能会上升,但如果没有,它可能不会发生。

    2011 年 1 月 26 日 上午 11:45

  12. JulienW

    Jethro,你不理解的是,严格模式让你能够减少错误:有了它,你可以在错误真正发生之前检测到它们。

    所有被“严格模式”删除的 JavaScript“功能”只是非常糟糕的做法。

    2011 年 1 月 26 日 下午 3:31

  13. uploading

    Firefox 非常独特。
    谢谢

    2011 年 1 月 29 日 下午 2:12

  14. OldDog

    我支持用严格规则迫使开发人员编写合适的代码,但“use strict”;真的吗,想不出更好的语法吗?

    怎么样?

    Object.useStrict;

    或者直接

    use strict; ?

    有什么问题?

    2011 年 2 月 27 日 上午 6:00

    1. Jeff Walden

      我并不反对。而且,考虑到有多少网站错误地、过早地、不正确地开始使用严格模式(将实际上不属于严格模式的东西标记为严格模式,例如对未声明的全局变量的赋值、`arguments.callee` 的使用等),我认为如果我们再做一遍,我们可能会选择一个不向后兼容的语法。但现在已经是覆水难收了。严格模式语法就是这样,没有必要为洒掉的牛奶而哭泣。

      2011 年 2 月 28 日 上午 11:14

  15. JulienW

    因为它必须与旧引擎向后兼容。

    2011 年 2 月 28 日 上午 8:27

  16. PabloCubico

    在开发中使用严格模式但在生产中不使用它会不会很危险?

    正如文档中所说:“严格模式更改语义”。因此,在生产中将其移除就相当于使用不支持它的浏览器。

    2011 年 6 月 4 日 上午 5:06

    1. JulienW

      据我所知(但我可能错了),“严格模式”是“传统 JavaScript”的一个子集。所以它应该是安全的。

      (对吗?)

      2011 年 6 月 6 日 上午 4:32

本文的评论已关闭。