严格模式
JavaScript 的严格模式是使用受限制的 JavaScript 的一种方式,从而隐式地“草率模式”。严格模式不仅仅是子集:这种模式有意地与普通情形下的有所区别。(MDN)
严格模式为 JavaScript
提供了更严格的运行环境。
开启严格模式后,部分特性会发生改变,如 this
指向 window
的不再指向 window
,而是变成了 undefined
。
function Test() {
'use strict';
console.log('this:', this);
}
Test(); // :this: undefined
单个 js 或者 script 的严格模式,可以通过在所有执行前 'use strict'
字符串开启。
'use strict';
function Test() {
console.log('this:', this);
}
Test(); // :this: undefined
在顶端协商 'use strict'
字符串,就可以打开整个的严格模式。
function testWith() {
'use strict';
var person = {
name: '鸽子天王',
age: ,
};
var age = ;
with (person) {
console.log(name);
console.log(age);
}
}
testWith();
在严格模式下是不提供 with
语句的的,所以这里会爆 Strict mode code may not include a with statement
。
在严格模式下是使用 with 语句的。
'use strict';
var person = {
name: '鸽子巨星',
};
with (person) {
console.log(name);
}
在严格模式下,变量必须被声明才能使用,否则会报错。
// 非严格模式下
number = ;
console.log(number); // :1
// 严格模式下
'use strict';
number = ; // 报错:ReferenceError: number is not defined
非严格模式下的 eval 作用域是其本身所在的作用域,而严格模式下,eval 执行过程中会创建新的作用域,并在结束后销毁。
// 非严格模式下
var number = ;
eval('var number = 3; console.log(number)'); // :3
console.log(number); // :3
// 严格模式下
'use strict';
var number = ;
eval('var number = 3; console.log(number)'); // :3
console.log(number); // :1
在非严格模式下,的 arguments
可以被重新赋值,在严格模式下,做赋值操作会报错。
function fn() {
console.log(arguments);
arguments = ;
console.log(arguments);
}
fn(, , );
'use strict';
function fn() {
console.log(arguments);
arguments = ;
console.log(arguments);
}
fn(, , );
在 this
章节中讨论了不同情况的指向,其中有一种情况的 this
是指向 window 的。
在严格模式中,这种情况下的 this
会变成 undefined
。
function testThis() {
console.log(this);
}
testThis();
// 严格模式下
'use strict';
function testThis() {
console.log(this);
}
testThis();
arguments.caller
可以到当前的的引用(该已经被标准废弃,不再使用了)。
arguments.callee
则可以到当前的引用。
这两个在严格模式下都被禁用。
function fn1() {
console.log(arguments.callee === fn1);
}
fn1();
'use strict';
function fn1() {
console.log(arguments.callee === fn1);
}
fn1();
在非严格模式下,这种情况会直接忽略。
var obj = {};
Object.defineProperty(obj, 'prop', {
conurable: false,
value: ,
});
console.log(obj);
delete obj.prop;
console.log(obj);
'use strict';
var obj = {};
Object.defineProperty(obj, 'prop', {
conurable: false,
value: ,
});
console.log(obj);
delete obj.prop;
console.log(obj);
在非严格模式下,这种情况会直接忽略。
var obj = {};
Object.defineProperty(obj, 'prop', {
writable: false,
value: ,
});
console.log(obj.prop);
obj.prop = ;
console.log(obj.prop);
'use strict';
var obj = {};
Object.defineProperty(obj, 'prop', {
writable: false,
value: ,
});
console.log(obj.prop);
obj.prop = ;
console.log(obj.prop);
八进制的表示是在数字前面加 0
,但其实 ECMAScript
标准中并没有这种表示法。
在 ES6 中提供了八进制数的表示方式,即在数字前 0o
前缀。
在严格模式下是使用 0
前缀表示的八进制字面量的。
// 非严格模式中
var num = ;
console.log(num); // :8
// 严格模式下
'use strict';
var num = ;
console.log(num); // :8
许多关键字在非严格模式下是可以当作变量名的。
var yield = ;
console.log(yield);
'use strict';
var yield = ;
console.log(yield);
根据 MDN
提供的,保留字有:
对严格模式大多数需要注意的是他带来的一些语法上的改变,特别是有些写法,在之前是不会报错的,开启严格模式后就会报错,如果没有进行处理,就会导致程序的中断。
以上对严格模式下的改变不一定是全部,可以参考 的文档。