天天看點

好程式員web前端教程之詳解JavaScript嚴格模式

  好程式員web前端教程之詳解JavaScript嚴格模式,嚴格模式(Strict mode)是由ECMA-262規範定義的新興JavaScript标準,釋出于2009年12月第五版。旨在改善錯誤檢查功能并且辨別可能不會延續到未來JavaScript版本的腳本。ES5嚴格模式是限制性更強的JavaScript變體,它與正常JavaScript的語義不同,其分析更為嚴格。

  目前,除了IE6-9,其它浏覽器均已支援ES5嚴格模式。

一、嚴格模式的使用

嚴格模式 的使用很簡單,隻有在代碼首部加入字元串 “use strict”。有兩種應用場景,一種是全局模式,一種是局部模式。

1)全局模式

'use strict'//code

2)局部模式

将”use strict”放到函數内的第一行,如下

function() {

"use strict";
//code}           

二、嚴格模式下的執行限制

1)不使用var聲明變量嚴格模式中将不通過

我們知道JS中,不使用var聲明的變量預設轉為全局變量。但在嚴格模式中将不允許,會報文法錯誤。

'use strict'g = 100 //錯誤

比如for循環

'use strict'for (i=0; i<5; i++) { //錯誤 console.log(i)}

2)任何使用’eval’的操作都會被禁止

'use strict'var obj = {}var eval = 3for (var eval in obj) {}function eval() {}function func(eval) {}

3)eval作用域 JS中作用域有兩種,全局作用域和函數作用域。嚴格模式帶來了第三種作用域:eval作用域,如下

'use strict'var a = 10eval('var a = 20; console.log(a)'); //20console.log(a) //10

4)with被禁用

'use strict'var obj = {

name:'zhangsan',

age:100,

sex:'男'}with(obj) { //報錯 console.log(name);

console.log(age);
console.log(sex);}           

5)caller/callee 被禁用

function func() {

'use strict'
arguments.callee
arguments.caller}func()           

6)對禁止擴充的對象添加新屬性會報錯

'use strict'var obj = {}Object.preventExtensions(obj)obj.a = 1 // 報錯

7)删除系統内置的屬性會報錯

'use strict'delete Object.prototype // 報錯delete Function.prototype // 報錯

8)delete使用var聲明的變量或挂在window上的變量報錯

'use strict'var obj = {a:1}window.a = 1delete obj // 報錯delete a // 報錯

9)delete不可删除屬性(isSealed或isFrozen)的對象時報錯

'use strict'var obj = {a: 1}Object.seal(obj)delete obj.a //報錯

10)對一個對象的隻讀屬性進行指派将報錯

'use strict'var obj = {}Object.defineProperty(obj, 'a', {value: 1, writable: false})obj.a = 2 // 報錯

11)函數有重名的參數将報錯

'use strict'function func(a, a) {

alert(a)}func()           

而在非嚴格模式中,後面的同名參數将覆寫前面的。

12)八進制表示法被禁用

'use strict'var num = 022

13)arguments嚴格定義為參數,不再與形參綁定

function func(a) {

arguments[0] = 2
alert(a) // 2}  func(1)           

func調用時傳參為1,函數内部通過arguments修改為2,此時alert的為修改後的2。 而在嚴格模式中則不能被修改,如下

'use strict'function func(a) {

arguments[0] = 2
alert(a) // 1}  func(1)           

14)函數必須聲明在頂層

我們知道函數聲明和函數表達式是兩個不同的概念。一般函數聲明都在最頂層,ES5前的JS寬松,你可以寫在if或for内。當然Firefox的解析方式與其他浏覽器不同,見SJ9002。而在嚴格模式中這些寫法将直接報錯

'use strict'if (true) {

function func1() { } // 文法錯誤}for (var i = 0; i < 5; i++) {
function func2() { } // 文法錯誤}           

15)ES5裡新增的關鍵字不能當做變量标示符使用,如implements, interface, let, package, private, protected, public, static, yield

'use strict'var let = 10 //報錯var yield = 20

16)call/apply的第一個參數直接傳入不包裝為對象

'use strict'function func() {

console.log(typeof this)}func.call('abcd') // stringfunc.apply(1)     // number           

依次為”string”,”number”。而在非嚴格模式中call/apply将對值類型的”abcd”,1包裝為對象後傳入,即兩次輸出都為”object”。

17)call/apply的第一個參數為null/undefined時,this為null/undefined 這裡以call來示例

console.log(this)}func.call(undefined) // undefinedfunc.call(null)      // null           

依次是undefined,null。而非嚴格模式中則是宿主對象,浏覽器裡是window,node.js環境則是global。

18)bind的第一個參數為null/undefined時,this為null/undefined bind是ES5給Function.prototype新增的一個方法,它和call/apply一樣在function上直接調用。它傳回一個指定了上下文和參數的函數。當它的第一個參數為null/undefined時,情形和call/apply一樣,this也為null/undefined。

console.log(this)}var f1 = func.bind(null)var f2 = func.bind(undefined)f1() // nullf2() // undefined           

而在非嚴格模式中輸出的都是window(或global)。

“use strict” 的位置必須在首部。首部指其前面沒有任何有效js代碼。以下都是無效的,将不會觸發嚴格模式。

a)“use strict” 前有代碼, 無效

var width = 10'use strict' g = 100

b)“use strict” 前有個空語句,無效

;//這裡是空語句'use strict' g = 100

;
'use strict'
g = 200}
           
;'use strict'
localVar = 200}           

當然,“use strict”前加注釋是可以的

// strict mode'use strict'g = 100

// strict mode    'use strict'
g = 200}func()           

繼續閱讀