use strict开启严格模式

ECMAScript 5的严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。[1]

启用方式

想启用严格模式,只需要执行如下代码即可

"use strict";
// ...更多代码

严格模式可以应用到一个script标签内或者单独的函数中,它必须位于所有其他代码之前,否则将不能启用严格模式,因此如果前端js代码进行过多文件合并,如果直接将js文件互相合并,有可能导致'use strict';不在第一行了,从而失去了作用。因此,最好的做法是尽量在一个函数内部(第一行)执行'use strict',这样既可以避免影响其他不需要在严格模式下执行的代码,也不会导致文件合并后,'use strict'没有在首行执行。

启用效果

  • 保留关键字不可作为变量名,包括implements, interface, let, package, private, protected, public, static和yield。
  • 函数声明只能在函数中或者脚本中,其他地方无法再进行函数声明。不过,下面的代码在Chrome中并不会报错,但仍然不建议这样使用

 var test = function(){
   'use strict';
   function ok(){ console.log('ok'); };
   ok();
   for(var i = 0; i< 1; i++){
      function fail(){ console.log('fail'); }
      fail();
   }
 };
test();

  • 全局变量必须显示声明,如果某个变量引用找不到,则不会转为创建全局变量。如代码段:test = 10,正常模式下,如果没有定义过test,这是则会创建一个新的全局变量test,而严格模式下,这一行为将抛出ReferenceError,从而避免了由于拼写错误等原因意外创建全局变量的情况
  • 结果异常的属性操作语句,都将抛出TypeError错误。比如,尝试给对象的只读属性赋值、删除congfigurable为false的属性或者给被Object.preventExtensions处理过的对象添加属性。
  • 严格模式要求一个对象内的所有属性名在对象内必须唯一,否则会引起TypeError错误。==但在Chrome浏览器的实际测试中,并没有报错。==出于跨浏览器兼容性考虑,还是遵循属性名称唯一的规则比较好。测试代码如下:


    var test = function ()
    {
    'use strict';
    var a = {'key':123,'key':'val'};
    console.log(a.key);
    }
    test();

  • 重名参数将直接报语法错误,例如代码

 var test = function(x,x,z){ 
     // 'use strict';
     console.log(x); 
  }; 
 test('a','b','c');

正常模式下,将输出'b';在严格模式下,执行这句var代码将报错:Uncaught SyntaxError: Duplicate parameter name not allowed in this context

  • 禁止8进制数字写法。虽然ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法,例如
    var abc = 010; 
    此时abc的的十进制结果为8,稍不注意就可能误以为是10。由于8进制不像16进制,存在ABCDEF等字符方便区别于10进制,8进制的表达方式最好不要使用,开启严格模式后,如果使用就会报错:Uncaught SyntaxError: Octal literals are not allowed in strict mode.
  • 禁用with,否则会报错Uncaught SyntaxError: Strict mode code may not include a with statement。虽然使用with有时可以简化代码书写,但有时可能导致变量引用发生混淆,考虑如下情况:

var obj = {'a':1,'b':2};
var b = 3;
with(obj){
console.log(b); //输出结果为2,如果想输出b=3的值,就要失望了
};

  • eval不会向其执行的上层context中添加新变量,用代码解释

var test = function(){
   'use strict';
   var a = 0;
   var b = eval('var a = 1;a');
    console.log('a:'+a+',b:'+b); // 严格模式下,结果为a:0,b:1 a没有被覆盖;正常模式下,结果为a:1,b:1 a被覆盖了
};

  • 禁止删除声明变量。如下代码将报错Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

var test = function(){
   'use strict';
   var a = 0;
   delete a;
};

但需要说明的是,这并不意味着delete都会引起报错。以下的代码都是可以正常执行的:


var test = function(){
  'use strict';
   var a = [0];
   delete a[0];
};
test();  //正常执行
test = function(){
  'use strict';
   var a = {'x':0,'y':1};
   delete a.x;
};
test(); //正常执行

  • eval、arguments不能被重新赋值,否则会报错Uncaught SyntaxError: Unexpected eval or arguments in strict mode
  • arguments的值不会被修改,始终保持传入的值。如以下代码所示

var test = function(a)
{
  'use strict';
  a = a+1;
  console.log(a == arguments[0]); 
};
test(0);  // 严格模式下arguments[0]仍然为0,输出false
// 正常模式下,arguments[0]的值变成1,输出为true
  • 不支持 arguments.callee,否则将报错Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode
  • 无法使用函数的caller属性和arguments属性,否则会报错Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context


    var test = function(){
    var func = function(){
    return [func.caller, func.arguments];
    };
    var caller = function(){
    return func();
    };
    console.log(caller()); // 正常模式可以正常执行,严格模式抛出异常
    };
  • arguments的caller属性无法访问,否则报错 Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

var test = function(a, b)
{
  "use strict";
  return arguments.caller; // 抛出异常
}
  • this指针不会被自动转换成对象。正常模式下,函数中的this会被强制转换成一个对象,或者指向全局对象,如下所示:

var test = function(){
    function fun() { return this; }
    console.log(fun());  // window对象
    console.log(fun.call(2));  // Number对象
    console.log(fun.apply(null)); // window对象
    console.log(fun.call(undefined)); // window对象
    console.log(fun.bind(true)()); // window对象
}

而在严格模式下,this就是调用时对应的值,没有指定就是undefined,看以下代码:


var test = function(){
  'use strict';
  function fun() { return this; }
  console.log(fun());  // undefined
  console.log(fun() === undefined); // true
  console.log(fun.call(2) === 2); // true
  console.log(fun.apply(null) === null); // true
  console.log(fun.call(undefined) === undefined); // true
  console.log(fun.bind(true)() === true); // true
}

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode ↩︎

Show Comments

Get the latest posts delivered right to your inbox.