mozilla
您的搜索结果

    向严格模式过渡

    ECMAScript 5 引入了 strict mode ,现在已经被大多浏览器实现(包括IE10. 会使web浏览器更容易的解析代码(只需要添加 "use strict"; 在源码的最上面), 由现有的代码到严格模式的过渡需要一些事做.

    该文章旨在为开发者提供指南.

    逐步过渡

    Strict mode has been thought so that the transition to it can be made gradually. It is possible to change each file individually and even to transition code to strict mode down to the function granularity.

    非严格模式到严格模式的区别

    语法错误

    如果代码中使用"use strict"开启了严格模式,则下面的情况都会在脚本运行之前抛出SyntaxError异常:

    • 八进制语法:var n = 023和var s = "\047"
    • with语句
    • 使用delete删除一个变量名(而不是属性名):delete myVariable
    • 使用evalarguments作为变量名或函数名
    • 使用未来保留字(也许会在ECMAScript 6中使用):implements, interface, let, package, private, protected, public, static,和yield作为变量名或函数名
    • 在语句块中使用函数声明:if(a<b){ function f(){} }
    • 其他错误
      • 对象子面量中使用两个相同的属性名:{a: 1, b: 3, a: 7}
      • 函数形参中使用两个相同的参数名:function f(a, b, b){}

    这些错误可以reveal plain errors or bad practices.They occur before the code is running.

    新的运行时错误

    JavaScript used to silently fails in contexts where what was done was an error. Strict mode throws in such cases. If your code base contains such cases, testing will be necessary to be sure nothing is broken. Once again, it can happen at the function granularity level.

    给一个未声明的变量赋值

    function f(x){
      "use strict";
      var a = 12;
      b = a + x*35; // error!
    }
    f();
    

    This used to change a value on the global object which is rarely the expected effect. If you really want to set a value to the global object, pass it as argument and explicitely assign as a property:

    var global = this; // in the top-level context, "this" always refers the global object
    function f(){
      "use strict";
      var a = 12;
      global.b = a + x*35;
    }
    f();
    

    尝试删除一个不可配置的属性

    "use strict";
    delete Object.prototype; // error!
    

    在非严格模式中,这样的代码只会静默失败,这样可能会导致用户误以为删除操作成功了.

    arguments对象和函数属性

    在严格模式下,访问arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都会抛出异常.The only legitimate use case would be to reuse a function as in:

    // example taken from vanillajs: http://vanilla-js.com/
    var s = document.getElementById('thing').style;
    s.opacity = 1;
    (function(){ 
      if((s.opacity-=.1) < 0)
        s.display="none";
      else
        setTimeout(arguments.callee, 40);
    })();

    可以重新写成:

    "use strict";
    var s = document.getElementById('thing').style;
    s.opacity = 1;
    (function fadeOut(){ // name the function
      if((s.opacity-=.1) < 0)
        s.display="none";
      else
        setTimeout(fadeOut, 40); // use the name of the function
    })();

    语义差异

    These differences are very subtle differences. It's possible that a test suite doesn't catch this kind of subtle differences. Careful review of your code base will probably be necessary to be sure these differences don't affect the semantics of your code. Fortunately, this careful review can be done gradually down the the function granularity.

    函数调用中的this

    在普通的函数调用f()中,this的值会指向全局对象.在严格模式中,this的值会指向undefined.当函数通过callapply调用时,如果传入的thisvalue参数是一个nullundefined除外的原始值(字符串,数字,布尔值),则this的值会成为那个原始值对应的包装对象,如果thisvalue参数的值是undefinednull,则this的值会指向全局对象.在严格模式中,this的值就是thisvalue参数的值,没有任何类型转换.

    arguments对象属性不与对应的形参变量同步更新

    在非严格模式中,修改arguments对象中某个索引属性的值,和这个属性对应的形参变量的值也会同时变化,反之亦然.This made optimizations complicated for JavaScript engine and made code harder to read/understand. In strict mode, the arguments object is created and initialized with the same values than the named arguments, but changes to either the arguments object or the named arguments aren't reflected in one another.

    eval相关的区别

    在严格模式中,eval不会在当前的作用域内创建新的变量.另外,传入eval的字符串参数也会按照严格模式来解析.Thorough testing will need to be performed to make sure nothing breaks. Not using eval if you don't really need it may be another very pragmatic solution.

    Strictness-neutral code

    A potential "downside" of moving strict code to strict mode is that the semantics may be different in legacy browsers which do not implement strict mode. In some rare occasions (like bad concatenation or minification), your code also may not run in the mode your wrote and tested it. Here are the rules to make your code strictness-neutral:

    1. Write your code as strict and make sure no strict-only errors (from the above "New runtime errors" section) are thrown.
    2. Stay away from semantic differences
      1. eval: use it only if you know what you're doing
      2. arguments: always access function arguments via their name or perform a copy of the arguments object using:
        var args = Array.prototype.slice.call(arguments)
        as the first line of your function
      3. this: only use this when it refers to an object you created.

    文档标签和贡献者

    此页面的贡献者有: ziyunfei, yenshen, teoli
    最后编辑者: ziyunfei,
    隐藏侧边栏