严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差别。
不支持严格模式的浏览器与支持严格模式的浏览器行为上也不同,因此不要在未经严格模式特性测试状况下使用严格模式。
严格模式能够与非严格模式共存,因此脚本能够逐渐的选择加入严格模式。数组
首先严格模式会将JavaScript陷阱直接变成明显的错误。
其次就是严格模式修正了一些引擎以优化的错误:一样的代码有时候严格模式会比非严格模式下更加流畅。
而后,严格模式禁用了一些有可能在将来版本中定义的语法。浏览器
若是想要在JavaScript中开启严格模式,首先要在全部代码的最前面,定义一个不会赋给任何变量的字符串。
若是以前的JavaScript代码是非严格模式的话,建议不要盲目的为这段代码开启严格模式,这样可能会出现问题。在初学时期建议按一个个的函数去开启严格模式。app
// 开启严格模式 - 做用于全局做用域 // "use strict" // 定义一个变量 - 不使用var关键字 a = 100; //在非严格模式中能够不使用var关键字,可是严格模式不能够,否则就会报错。 console.log(a); function fn(){ // 开启严格模式 - 做用于函数做用域 "use strict" v = 200; console.log(v); } fn();
严格模式也能够为一个指定的函数开启。dom
function fn(){ 'use strict' //在函数体中开启严格模式,可是函数意外依旧是非严格模式 v = 200; consolo.log(v); } fn();
在严格模式的状况下,是不容许建立全局变量的。函数
// 开启严格模式 "use strict"; v = 100;//不使用var关键字 console.log(v); function fn(){ // 在非严格模式:在函数做用域中定义变量 - 不使用var关键字 -> 自动将其提高为全局变量 w = 200; console.log(w); } fn(); console.log(w);
所谓的静默失败就是即不报错也没有任何效果。例如改变常量的值。在严格模式下,静默失败会转换成抛出异常。测试
// 开启严格模式 "use strict"; const v = 3.14;// 定义常量 v = 1.14;// 从新赋值。严格模式下结果报错。 console.log(v);
在严格模式下,不能使用变量使用delete运算符,可是这种状况只针对变量,对数组和对象属性没有限制。优化
// 开启严格模式 "use strict"; // 严格模式下禁用delete关键字 -> 针对删除变量,而不是数组元素和对象属性 // var v = 100;// 定义一个全局变量 // console.log(v); // // delete v;// 删除全局变量v // console.log(v);// undefined 定义数组 // var arr = [1,2,3,4,5]; // delete arr[0]; // console.log(arr); 定义对象 var obj = { name : '张无忌' } delete obj.name; console.log(obj.name);
在严格模式下,JavaScript对变量名也有限制。特别不能使用以下内容做为变量:this
上述内容都是保留字,在ECMAScript的下一个版本中可能会用到他们。
可是在严格模式下,使用上述标示符做为变量名会致使语法错误。spa
// 开启严格模式 "use strict"; var static = 100; console.log(static);//结果-报错
在严格模式下,不能使用delete运算符删除不可删除的属性。prototype
开启严格模式 "use strict"; //在非严格模式下使用delete删除不可删除的属性 delete Object.prototype;//结果会静默失败 console.log(Object.prototype); //在严格模式下使用delete删除不可删除额属性,结果就是抛出异常。 delete Math.random; console.log(Math.random); // Math.random();
在严格模式下,一个对象的全部属性名在对象内必须惟一。
// 开启严格模式 "use strict"; //在非严格模式下重名是容许的,最后一个重名的属性就会覆盖以上的属性 //当开启严格模式,重名属性就会被认为是语法错误 var obj = { name : '张三', name : '李四' } console.log(obj.name);
在严格模式下,不能为一个只读的属性进行从新赋值。
// 开启严格模式 "use strict"; var obj = { name : '张无忌' } // 用于判断指定属性是否为只读属性 var result = Object.getOwnPropertyDescriptor(obj, 'name'); console.log(result);//在非严格模式下为只读属性从新赋值,结果会为静默失败。 // 定义对象obj的只读属性 Object.defineProperty(obj, 'age', { value : 18 }); // 针对只读属性进行修改操做 // obj.age = 80; // console.log(obj.age); delete obj.age; console.log(obj.age);
在严格模式下,不能为不可扩展的对象添加新属性。
// 开启严格模式 "use strict"; var obj = {}; // 设置对象obj是一个不可扩展的对象 Object.preventExtensions(obj); // 为对象obj新增属性 obj.name = '张无忌'; console.log(obj); //在非严格模式下为不可扩展的对象添加新属性,结果是静默失败。
在严格模式下,要求命名函数的参数必须惟一。
// 开启严格模式 "use strict"; function fn(a, a, b){ console.log(a + a + b); //在非严格模式下最后一个参数名就会以前的重名参数,以前的参数仍然能够铜鼓arguments[i]来访问。 //在开启严格模式下,重名参数就会被认为是语法错误。 } fn(1,2,3);
在严格模式下,arguments对象的行为也有所不一样。
1.在非严格模式下,修改命名参数的值也会反应到arguments对象中。
2.在严格模式下,命名参数与arguments对象是彻底独立的。
// 开启严格模式 "use strict"; function fn(value){ var value = '张无忌'; console.log(value);// 张无忌 -> 就近原则 /* * 非严格模式下 - arguments对象获取参数的值与形参有关的 * 若是局部变量与形参名相同 - 根据就近原则进行获取 * 严格模式下 - arguments对象获取参数的值与形参无关的 */ console.log(arguments[0]);// 张无忌 } fn('周芷若');
在严格模式下,不能使用arguments对象的callee()方法。
// 开启严格模式 "use strict"; //在非严格模式下,arguments对象callee()方法,表示调用函数自己 // 在严格模式下,arguments对象没法调用callee()方法,结果抛出异常 function fn(){ console.log(arguments.length); // return arguments.callee; } fn();
在严格模式下,只能在全局域和函数域中声明函数。
// 开启严格模式 "use strict"; // 在全局做用域 function fn(){ // 在函数做用域 function n(){} //在非严格模式下,函数的定义在人格位置声明函数都是能够的。 } // 在严格模式下,函数的定义只能在全局做用域与函数做用域(不能在块级做用域定义函数),语法错误 for (var i=0; i<10; i++) { // ECMAScript 6新增 - 存在着块级做用域 var v = 100; function f(){ console.log('this is function'); } } console.log(v); f();
在严格模式下使用eval()函数建立的变量只能在eval()函数内部使用。
// 开启严格模式 "use strict"; //在非严格模式下eval()函数建立的变量在其余位置能够使用。 // 在严格模式下,增长eval做用域 - eval()函数定义的变量只能在当前eval()函数内部使用 eval('var v = 100;'); // 在全局做用域中调用变量 - 报错 console.log(v);// 100
在严格模式下,禁止使用eval()和arguments做为标示符,也不容许读写它们的值。
1.使用var声明
2.赋值另外一个值
3.尝试修改包含的值
4.用做函数名
5.用做命名的函数的参数
6.在try...catch语句中用做例外明
// 开启严格模式 "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;");
在非严格模式下使用函数的apply()或call()方法时,null或undefined值会被转换为全局对象。
在严格模式下,函数的this值始终是指定的值(不管什么值)。
// 开启严格模式 "use strict"; var v = 100; function fn(){ console.log(this.v); } var obj = { v : 200 } fn.call(obj);// this指向全局对象