严格模式(Strict mode)是由ECMA-262规范定义的新兴JavaScript标准,第五版发布于2009年12月。旨在改善错误检查功能并且标识可能不会延续到未来JavaScript版本的脚本。ES5严格模式是限制性更强的JavaScript变体,它与常规JavaScript的语义不同,其分析更为严格。
目前,除了IE6-9,其它浏览器均已支持ES5严格模式。
一、严格模式的使用
严格模式的使用很简单,只有在代码首部加入字符串 "use strict"。有两种应用场景,一种是全局模式,一种是局部模式。
1)全局模式
'use strict' var globalVal = 100 console.log(globalVal)
执行后输出了100,与非严格模式没什么区别。
2)局部模式
将"use strict"放到函数内的第一行,如下
function func() { 'use strict' var localVal = 200 console.log(localVal) } func()
执行后输出了200,与非严格模式也没用什么区别。
3)模块模式
如果你想定义一个模块或者一个小库,自然采用一个匿名函数自执行是不错的选择
~function() { "use strict"; // Define your library strictly... }();
“use strict” 的位置是很讲究的,必须在首部。首部指其前面没有任何有效js代码。以下都是无效的,将不会触发严格模式。
a)“use strict” 前有代码
var width = 10 'use strict' globalVar = 100
b)“use strict” 前有个空语句都不行
; 'use strict' globalVar = 100
或
function func() { ; 'use strict' localVar = 200 }
或
function func() { ;'use strict' localVar = 200 }
当然,“use strict”前加注释是可以的
// strict mode 'use strict' globalVar = 100
或
function func() { // strict mode 'use strict' localVar = 200 } func()
二、严格模式下的执行限制
上面举的两个例子,在严格模式中输出与普通模式没用什么区别。下面就不一样了。
1)不使用var声明变量严格模式中将不通过
我们知道JS是弱类型,宽松的语言。不使用var声明的变量默认转为全局变量。但在严格模式中将不允许,会报语法错误。
'use strict' globalVal = 100
执行,Firebug提示如下
又如全局的for循环
'use strict' for (i=0; i<5; i++) { console.log(i) }
这种写法在非严格模式中很危险,i 会不小心溢出成为全局变量。但在严格模式中会报错
局部模式
function func() { 'use strict' localVal = 200 console.log(localVal) } func()
执行,Firebug报错
因此,严格模式中声明变量务必记得加一个var。
2)任何使用'eval'的操作都会被禁止
'use strict' var obj = {} var eval = 3 obj.eval = 1 obj.a = eval for (var eval in obj) {} function eval() {} function func(eval) {} var func = new Function('eval')
Firebug报错
3)eval作用域
JS中作用域有两种,全局作用域和函数作用域。严格模式带来了第三种作用域:eval作用域,如下
'use strict' var a = 10 eval('var a = 20; console.log(a)') console.log(a)
Firebug控制台依次输出了20,10。eval是在全局模式下(非函数内)的,如果不加严格模式,此时修改的是全局的a。即输出20,20。见 eval与window.eval的差别。
4)with被禁用
'use strict' with({a:1}) { }
Firebug报错
5)caller/callee 被禁用
function func() { 'use strict' arguments.callee arguments.caller } func()
Firebug报错
6)对禁止扩展的对象添加新属性会报错
'use strict' var obj = {} Object.preventExtensions(obj) obj.a = 1 // 报错
Firebug报错
7)删除系统内置的属性会报错
'use strict' delete Object.prototype // 报错 delete Function.prototype // 报错
Firebug报错
8)delete使用var声明的变量或挂在window上的变量报错
'use strict' var obj = {a:1} window.a = 1 delete obj // 报错 delete a // 报错
Firebug报错如下
9)delete不可删除属性(isSealed或isFrozen)的对象时报错
'use strict' var obj = {a: 1} Object.seal(obj) delete obj.a
Firebug报错如下
10)对一个对象的只读属性进行赋值将报错
'use strict' var obj = {} Object.defineProperty(obj, 'a', {value: 1, writable: false}) obj.a = 2 // 报错
Firebug报错如下
11)对象有重名的属性将报错
'use strict' var obj = { a: 1, a: 2 }
Firebug报错如下
而在非严格模式中,后面的属性将覆盖前面的属性,即obj.a等于2。
12)函数有重名的参数将报错
'use strict' function func(a, a) { alert(a) } func()
Firebug报错
而在非严格模式中,后面的同名参数将覆盖前面的。
13)八进制表示法被禁用
'use strict' var num = 022
Firebug报错如下
14)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)
显示的严格的为传入的1。
其实有点还有点复杂,如果alert的是arguments[0],实际在严格模式中仍然被修改为2了。如下
'use strict' function func(a) { arguments[0] = 2 alert(arguments[0]) // 2 } func(1)
可以参考下 仅Chrome中函数实参与形参发生关联
15)函数必须声明在顶层
我们知道函数声明和函数表达式是两个不同的概念。一般函数声明都在最顶层,ES5前的JS宽松,你可以写在if或for内(强烈鄙视这种写法)。当然Firefox的解析方式与其他浏览器不同,见SJ9002。而在严格模式中这些写法将直接报错
'use strict' if (true) { function func1() { } // 语法错误 } for (var i = 0; i < 5; i++) { function func2() { } // 语法错误 }
Firebug报错
16)ES5里新增的关键字不能当做变量标示符使用,如implements, interface, let, package, private, protected, public, static, yield
'use strict' var let = 10 var yield = 20
Firebug报错
17)call/apply的第一个参数直接传入不包装为对象
'use strict' function func() { console.log(typeof this) } func.call('abcd') // string func.apply(1) // number
Firebug输出如下
依次为"string","number"。而在非严格模式中call/apply将对值类型的"abcd",1包装为对象后传入,即两次输出都为"object"。
18)call/apply的第一个参数为null/undefined时,this为null/undefined
这里以call来示例
'use strict' function func() { console.log(this) } func.call(undefined) // undefined func.call(null) // null
Firebug输出了undefined和null,而非严格模式中则是宿主对象,浏览器里是window,node.js环境则是global。
19)bind的第一个参数为null/undefined时,this为null/undefined
bind是ES5给Function.prototype新增的一个方法,它和call/apply一样在function上直接调用。它返回一个指定了上下文和参数的函数。当它的第一个参数为null/undefined时,情形和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
而在非严格模式中输出的都是window(或global)。
相关:
http://msdn.microsoft.com/library/br230269.aspx
http://java-script.limewebs.com/strictMode/test_hosted.html
http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/
http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/
相关推荐
两种用法:全局严格模式局部函数内严格模式(推荐)严格模式和ES3模式的区别改变作用域链的最顶端(将obj作为此代码块的作用域最顶端,通常配合命名空间使用)} /
// try{ // console.log(a); // console.log(b); // console.log(c) ... //es5.0严格模式的启动 // function test() { // console.log(arguments.callee); // } // test(); // function de
ES5严格模式的启用为开发者提供了更好的控制和错误检测,有利于写出更安全、更易于维护的代码。通过在库代码内部使用立即执行函数表达式(IIFE)并启用严格模式,可以确保库的内部一致性,而不会影响外部非严格模式...
1. **严格模式**:ES5引入了"use strict"指令,这使得开发者可以选择性地启用严格模式,它会禁用一些可能导致错误或者不明确的行为,提高了代码质量。 2. **对象字面量和数组字面量改进**:允许在对象字面量中使用...
3. 访问arguments.callee或函数的caller属性将导致“类型错误(TypeError)” 4. 以下代码的执行效果与非严格模式并不一致:js
- **ES5 严格模式** 提供了更严格的错误检查,并禁止了一些不安全的行为。 - 在模块的顶层添加 `'use strict';` 语句。 - **引入 ES6 模块:** - **ES6 模块** 是 JavaScript 的原生模块系统,提供了更简洁的...
需要注意的是,`arguments.callee`在ES5严格模式下是被禁止的,因为它可能造成性能问题和难以调试的代码。因此,在现代JavaScript编程中,通常推荐使用闭包或者函数名引用代替`arguments.callee`。 总结,`...
然而,由于这种用法可能导致难以调试的代码,ES5严格模式下会禁止使用arguments.callee。 4. **apply方法** apply是Function对象的一个方法,允许改变函数调用的上下文(即this值)以及传入参数。它接受两个参数:...
`es5-shim.js`不会直接开启严格模式,但会尽量模仿其行为。 7. **JSON支持**:ES5添加了内置的JSON解析和字符串化功能。在旧版浏览器中,`es5-shim.js`提供了一个JSON polyfill。 8. **对象扩展**:`Object.keys()...
1. **严格模式**('use strict'):ES5引入了严格模式,这是一种特殊的执行上下文,可以限制某些可能引起错误的行为,如变量未声明就使用,或者禁止删除变量等。 2. **对象字面量属性简写**:允许在创建对象时省略...
什么是侏罗纪? 侏罗纪是ECMAScript语言和运行时的实现。 它旨在为.NET提供性能最佳,最符合标准JavaScript实现。 侏罗纪不适合e侏罗纪是什么?...功能支持所有ECMAScript 3和ECMAScript 5功能,包括ES5严格模式
JavaScript this指向总结 在JavaScript中this永远指向当前函数的主人,即函数的...注:在es5严格模式下,this禁止指向window,会报错 对象的方法中,this指向调用当前方法的对象 var person = { username: 钢铁侠,
此外,为了确保最佳效果,建议在引入`es5-shim`之后立即启用严格模式,通过在脚本开头添加`'use strict';`。 **注意事项** 尽管`es5-shim`能够显著改善旧浏览器的兼容性,但它并不能解决所有问题。有些ES5特性,如...
产品特点支持所有ECMAScript 3和ECMAScript 5功能,包括ES5严格模式经过良好测试-通过超过五千次单元测试(包含三万多个断言) 简单而强大的API 将JavaScript编译成.NET字节码(CIL); 不是口译员部署为单个.NET...
严格模式是ES5引入的新特性,它改变了JavaScript的一些默认行为,使得开发者能够更加精确地控制代码的运行。在标题提到的“some-non-strict-module”是一个NPM模块,其代码并未遵循严格模式,这可能意味着该模块可能...
在ES5中,我们可以在函数体内通过在开头添加`'use strict'`来启用严格模式。例如: ```javascript function doSomething(a, b) { 'use strict'; // 函数体代码 } ``` 然而,ES2016(即ES6)对这一规则进行了一些...
4. **ES5严格模式禁用**:在ES5的严格模式下,`with`语句是被禁止使用的,因为它被视为不安全和不推荐的语法。 鉴于这些缺点,开发人员通常避免使用`with`语句。替代方案包括: 1. **变量别名**:创建一个指向复杂...
接下来,严格模式('use strict')是ES5引入的一个新的功能。通过在脚本或者函数的顶部添加'use strict',可以开启严格模式。严格模式的目的是让JavaScript代码运行在一个更严格的环境中,它禁止了一些不安全和不...
但需要注意的是,`arguments.callee`在ES5严格模式下被移除,因此在严格模式中不能使用这个属性。 3. 使用`this.constructor === arguments.callee`判断方法: - 这种方法通过比较上下文的构造器属性和当前正在...