嚴(yán)格模式(Strict mode)是由ECMA-262規(guī)范定義的新興JavaScript標(biāo)準(zhǔn),發(fā)布于2009年12月第五版。旨在改善錯(cuò)誤檢查功能并且標(biāo)識(shí)可能不會(huì)延續(xù)到未來(lái)JavaScript版本的腳本。ES5嚴(yán)格模式是限制性更強(qiáng)的JavaScript變體,它與常規(guī)JavaScript的語(yǔ)義不同,其分析更為嚴(yán)格。
目前,除了IE6-9,其它瀏覽器均已支持ES5嚴(yán)格模式。
一、嚴(yán)格模式的使用
嚴(yán)格模式 的使用很簡(jiǎn)單,只有在代碼首部加入字符串 “use strict”。有兩種應(yīng)用場(chǎng)景,一種是全局模式,一種是局部模式。
1)全局模式
'use strict'
//code
2)局部模式
將”use strict”放到函數(shù)內(nèi)的第一行,如下
function() {
"use strict";
//code
}
二、嚴(yán)格模式下的執(zhí)行限制
1)不使用var聲明變量嚴(yán)格模式中將不通過(guò)
我們知道JS中,不使用var聲明的變量默認(rèn)轉(zhuǎn)為全局變量。但在嚴(yán)格模式中將不允許,會(huì)報(bào)語(yǔ)法錯(cuò)誤。
'use strict'
g = 100 //錯(cuò)誤
比如for循環(huán)
'use strict'
for (i=0; i<5; i++) { //錯(cuò)誤
console.log(i)
}
2)任何使用’eval’的操作都會(huì)被禁止
'use strict'
var obj = {}
var eval = 3
for (var eval in obj) {}
function eval() {}
function func(eval) {}
3)eval作用域 JS中作用域有兩種,全局作用域和函數(shù)作用域。嚴(yán)格模式帶來(lái)了第三種作用域:eval作用域,如下
'use strict'
var a = 10
eval('var a = 20; console.log(a)'); //20
console.log(a) //10
4)with被禁用
'use strict'
var obj = {
name:'zhangsan',
age:100,
sex:'男'
}
with(obj) { //報(bào)錯(cuò)
console.log(name);
console.log(age);
console.log(sex);
}
5)caller/callee 被禁用
function func() {
'use strict'
arguments.callee
arguments.caller
}
func()
6)對(duì)禁止擴(kuò)展的對(duì)象添加新屬性會(huì)報(bào)錯(cuò)
'use strict'
var obj = {}
Object.preventExtensions(obj)
obj.a = 1 // 報(bào)錯(cuò)
7)刪除系統(tǒng)內(nèi)置的屬性會(huì)報(bào)錯(cuò)
'use strict'
delete Object.prototype // 報(bào)錯(cuò)
delete Function.prototype // 報(bào)錯(cuò)
8)delete使用var聲明的變量或掛在window上的變量報(bào)錯(cuò)
'use strict'
var obj = {a:1}
window.a = 1
delete obj // 報(bào)錯(cuò)
delete a // 報(bào)錯(cuò)
9)delete不可刪除屬性(isSealed或isFrozen)的對(duì)象時(shí)報(bào)錯(cuò)
'use strict'
var obj = {a: 1}
Object.seal(obj)
delete obj.a //報(bào)錯(cuò)
10)對(duì)一個(gè)對(duì)象的只讀屬性進(jìn)行賦值將報(bào)錯(cuò)
'use strict'
var obj = {}
Object.defineProperty(obj, 'a', {value: 1, writable: false})
obj.a = 2 // 報(bào)錯(cuò)
11)函數(shù)有重名的參數(shù)將報(bào)錯(cuò)
'use strict'
function func(a, a) {
alert(a)
}
func()
而在非嚴(yán)格模式中,后面的同名參數(shù)將覆蓋前面的。
12)八進(jìn)制表示法被禁用
'use strict'
var num = 022
13)arguments嚴(yán)格定義為參數(shù),不再與形參綁定
function func(a) {
arguments[0] = 2
alert(a) // 2
}
func(1)
func調(diào)用時(shí)傳參為1,函數(shù)內(nèi)部通過(guò)arguments修改為2,此時(shí)alert的為修改后的2。 而在嚴(yán)格模式中則不能被修改,如下
'use strict'
function func(a) {
arguments[0] = 2
alert(a) // 1
}
func(1)
14)函數(shù)必須聲明在頂層
我們知道函數(shù)聲明和函數(shù)表達(dá)式是兩個(gè)不同的概念。一般函數(shù)聲明都在最頂層,ES5前的JS寬松,你可以寫(xiě)在if或for內(nèi)。當(dāng)然Firefox的解析方式與其他瀏覽器不同,見(jiàn)SJ9002。而在嚴(yán)格模式中這些寫(xiě)法將直接報(bào)錯(cuò)
'use strict'
if (true) {
function func1() { } // 語(yǔ)法錯(cuò)誤
}
for (var i = 0; i < 5; i++) {
function func2() { } // 語(yǔ)法錯(cuò)誤
}
15)ES5里新增的關(guān)鍵字不能當(dāng)做變量標(biāo)示符使用,如implements, interface, let, package, private, protected, public, static, yield
'use strict'
var let = 10 //報(bào)錯(cuò)
var yield = 20
16)call/apply的第一個(gè)參數(shù)直接傳入不包裝為對(duì)象
'use strict'
function func() {
console.log(typeof this)
}
func.call('abcd') // string
func.apply(1) // number
依次為”string”,”number”。而在非嚴(yán)格模式中call/apply將對(duì)值類(lèi)型的”abcd”,1包裝為對(duì)象后傳入,即兩次輸出都為”object”。
17)call/apply的第一個(gè)參數(shù)為null/undefined時(shí),this為null/undefined 這里以call來(lái)示例
'use strict'
function func() {
console.log(this)
}
func.call(undefined) // undefined
func.call(null) // null
依次是undefined,null。而非嚴(yán)格模式中則是宿主對(duì)象,瀏覽器里是window,node.js環(huán)境則是global。
18)bind的第一個(gè)參數(shù)為null/undefined時(shí),this為null/undefined bind是ES5給Function.prototype新增的一個(gè)方法,它和call/apply一樣在function上直接調(diào)用。它返回一個(gè)指定了上下文和參數(shù)的函數(shù)。當(dāng)它的第一個(gè)參數(shù)為null/undefined時(shí),情形和call/apply一樣,this也為null/undefined。
'use strict'
function func() {
console.log(this)
}
var f1 = func.bind(null)
var f2 = func.bind(undefined)
f1() // null
f2() // undefined
而在非嚴(yán)格模式中輸出的都是window(或global)。
“use strict” 的位置必須在首部。首部指其前面沒(méi)有任何有效js代碼。以下都是無(wú)效的,將不會(huì)觸發(fā)嚴(yán)格模式。
a)“use strict” 前有代碼, 無(wú)效
var width = 10
'use strict'
g = 100
b)“use strict” 前有個(gè)空語(yǔ)句,無(wú)效
;//這里是空語(yǔ)句
'use strict'
g = 100
function func() {
;
'use strict'
g = 200
}
function func() {
;'use strict'
localVar = 200
}
當(dāng)然,“use strict”前加注釋是可以的
// strict mode
'use strict'
g = 100
function func() {
// strict mode
'use strict'
g = 200
}
func()