概述
严格模式是什么
严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。
不支持严格模式的浏览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。
严格模式可以与非严格模式共存,所以脚本可以逐渐的选择加入严格模式。
严格模式的目的
首先严格模式会将JavaScript陷阱直接变成明显的错误。
其次就是严格模式修正了一些引擎以优化的错误:同样的代码有时候严格模式会比非严格模式下更加流畅。
然后,严格模式禁用了一些有可能在未来版本中定义的语法。
开启严格模式
全局开启严格模式
如果想要在JavaScript中开启严格模式,首先要在所有代码的最前面,定义一个不会赋给任何变量的字符串。
如果之前的JavaScript代码是非严格模式的话,建议不要盲目的为这段代码开启严格模式,这样可能会出现问题。在初学时期建议按一个个的函数去开启严格模式。
// 开启严格模式 - 作用于全局作用域
// "use strict"
// 定义一个变量 - 不使用var关键字
a = 100;
//在非严格模式中可以不使用var关键字,但是严格模式不可以,不然就会报错。
console.log(a);
function fn(){
// 开启严格模式 - 作用于函数作用域
"use strict"
v = 200;
console.log(v);
}
fn();
函数开启严格模式
严格模式也可以为一个指定的函数开启。
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关键字
在严格模式下,不能使用变量使用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对变量名也有限制。特别不能使用如下内容作为变量:
上述内容都是保留字,在ECMAScript的下一个版本中可能会用到他们。
但是在严格模式下,使用上述标示符作为变量名会导致语法错误。
// 开启严格模式
"use strict";
var static = 100;
console.log(static);//结果-报错
对象
不可删除的属性
在严格模式下,不能使用delete运算符删除不可删除的属性。
开启严格模式
"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的不同
在严格模式下,arguments对象的行为也有所不同。
1.在非严格模式下,修改命名参数的值也会反应到arguments对象中。
2.在严格模式下,命名参数与arguments对象是完全独立的。
// 开启严格模式
"use strict";
function fn(value){
var value = '张无忌';
console.log(value);// 张无忌 -> 就近原则
/*
* 非严格模式下 - arguments对象获取参数的值与形参有关的
* 如果局部变量与形参名相同 - 根据就近原则进行获取
* 严格模式下 - arguments对象获取参数的值与形参无关的
*/
console.log(arguments[0]);// 张无忌
}
fn('周芷若');
arguments.callee()
在严格模式下,不能使用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()作用域
在严格模式下使用eval()函数创建的变量只能在eval()函数内部使用。
// 开启严格模式
"use strict";
//在非严格模式下eval()函数创建的变量在其他位置可以使用。
// 在严格模式下,增加eval作用域 - eval()函数定义的变量只能在当前eval()函数内部使用
eval('var v = 100;');
// 在全局作用域中调用变量 - 报错
console.log(v);// 100
arguments对象
禁止读写
在严格模式下,禁止使用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;");
this关键字
抑制this
在非严格模式下使用函数的apply()或call()方法时,null或undefined值会被转换为全局对象。
在严格模式下,函数的this值始终是指定的值(无论什么值)。
// 开启严格模式
"use strict";
var v = 100;
function fn(){
console.log(this.v);
}
var obj = {
v : 200
}
fn.call(obj);// this指向全局对象
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。