066_严格模式

1. "use strict"指令

1.1. "use strict"是JavaScript 1.8.5中的新指令(ECMAScript version 5)。

1.2. 它不算一条语句, 而是一段文字表达式, 更早版本的JavaScript会忽略它。

1.3. "use strict";的作用是指示JavaScript代码应该以"严格模式"执行。

1.4. 以下版本的浏览器支持严格模式:

  • 版本10以后的IE
  • 版本4以后的Firefox
  • 版本13以后的Chrome
  • 版本5.1以后的Safari

2. 声明严格模式

2.1. 通过在脚本或函数的开头添加"use strict";来声明严格模式。

2.2. 在脚本开头进行声明, 拥有全局作用域(脚本中的所有代码均以严格模式来执行):

<script type="text/javascript">
	"use strict";
	function myFn1(){
		document.write(this + '<br />');
	}
	myFn1();
</script>

2.3. 同一页面中多个脚本, 可以是默认模式, 也可以是严格模式, 互不影响:

<script type="text/javascript">
	"use strict";
	function myFn1(){
		document.write(this + '<br />');
	}
	myFn1();
</script>

<script type="text/javascript">
	function myFn2(){
		document.write(this + '<br />');
	}
	myFn2();
</script>

2.4. 在函数中声明严格模式, 拥有局部作用域(只有函数中的代码以严格模式执行):

function myFn3(){
	"use strict";
	document.write(this + '<br />');
}
myFn3();

2.5. "use strict"指令只能在脚本或函数的开头被识别。

3. 为什么使用严格模式?

3.1. 严格模式使我们更容易编写"安全的"JavaScript。

3.2. 严格模式把之前可接受的"坏语法"转变为真实的错误。

4. 严格模式中不允许的事项

4.1. 在不声明变量的情况下使用变量, 是不允许的:

<script type="text/javascript">
	"use strict";

	// 报错, 严格模式中, 在不声明变量的情况下使用变量, 是不允许的
	a = 5;
</script>

<script type="text/javascript">
	// 默认模式中, 在不声明变量的情况下使用变量, 成为全局变量
	b = 10;
</script>

4.2. 使用delete删除变量是不允许的:

<script type="text/javascript">
	"use strict";	
	var c = 15;
	// 报错, 严格模式中, 使用delete删除变量, 是不允许的
	delete c;
</script>

<script type="text/javascript">
	var d = 20;
	// 默认模式中, 使用delete删除变量, 没有任何影响
	delete d;
	document.write('d = ' + d + '<br />');
</script>

4.3. 使用delete删除函数是不允许的:

<script type="text/javascript">
	"use strict";	
	function myFn1(){
		document.write(this + '<br />');
	}

	// 报错, 严格模式中, 使用delete删除函数, 是不允许的
	delete myFn1;
</script>

<script type="text/javascript">
	function myFn2(){
		document.write(this + '<br />');
	}

	// 默认模式中, 使用delete删除函数, 没有任何影响
	delete myFn2;
	myFn2();
</script>

4.4 重复使用参数名, 是不允许的:

<script type="text/javascript">
	"use strict";	
	// 报错, 严格模式中, 重复使用参数名, 是不允许的
	function myFn4(p1, p1){
		document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');
	}
	myFn4(25, 30);
</script>

<script type="text/javascript">
	// 默认模式中, 重复使用参数名, 参数值是最后一个实参的值
	function myFn5(p1, p1){
		document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');
	}
	myFn5(35, 40);
</script>

4.5. 八进制数值是不允许的:

<script type="text/javascript">
	"use strict";
	// 报错, 严格模式中, 八进制数值是不允许的
	document.write('e = ' + 010 + '<br />');
</script>

<script type="text/javascript">
	// 默认模式中, 八进制数值是允许的
	document.write('f = ' + 020 + '<br />');
</script>

4.6. 八进制转义字符是不允许的:

<script type="text/javascript">
	"use strict";
	// 报错, 严格模式中, 八进制转义字符是不允许的:
	document.write('\077' + '<br />');
</script>

<script type="text/javascript">
	// 默认模式中, 八进制转义字符是允许的
	document.write('\077' + '<br />');
</script>

4.7. 写入只读属性是不允许的:

<script type="text/javascript">
	"use strict";
	var obj1 = {get Id(){return this.id;}};
	Object.defineProperty(obj1, 'id', {value: 1001, writable: false});
	// 报错, 严格模式中, 写入只读属性是不允许的
	obj1.id = 1002;
	document.write('obj1.id = ' + obj1.id + '<br />');
</script>

<script type="text/javascript">
	var obj2 = {get Id(){return this.id;}};
	Object.defineProperty(obj2, 'id', {value: 10001, writable: false});
	// 默认模式中, 写入只读属性, 不会报错, 但也不会赋值
	obj2.id = 10002;
	document.write('obj2.id = ' + obj2.id + '<br />');
</script>

4.8. 写入只能获取的属性是不允许的:

<script type="text/javascript">
	"use strict";
	var obj1 = {get Id(){return this.id;}};
	Object.defineProperty(obj1, 'id', {value: 1001, writable: false});
	// 报错, 严格模式中, 写入只能获取的属性是不允许的
	obj1.Id = 1003;
	document.write('obj1.Id = ' + obj1.Id + '<br />');
</script>

<script type="text/javascript">
	var obj2 = {get Id(){return this.id;}};
	Object.defineProperty(obj2, 'id', {value: 10001, writable: false});
	// 默认模式中, 写入只能获取的属性, 不会报错, 但也不会赋值
	obj2.Id = 10003;
	document.write('obj2.Id = ' + obj2.Id + '<br />');
</script>

4.9. 删除不可删除的属性是不允许的:

<script type="text/javascript">
	"use strict";
	// 报错, 严格模式中, 删除不可删除的属性是不允许的
	delete Object.prototype;
</script>

<script type="text/javascript">
	// 默认模式中, 删除不可删除的属性, 没有任何影响
	delete Object.prototype;
	document.write('Object.prototype = ' + Object.prototype + '<br />');
</script>

4.10. 处于安全考虑, eval()在其被调用的作用域中创建的变量, 在其它作用域中不允许:

<script type="text/javascript">
	"use strict";
	eval("var drink1 = '红茶';document.write('drink1 = ' + drink1 + '<br />');");
	// 报错, 严格模式中, eval()在其被调用的作用域中创建的变量, 在其它作用域中不允许
	document.write('drink1 = ' + drink1 + ', window.drink1 = ' + window.drink1 + '<br />');
</script>

<script type="text/javascript">
	eval("var drink2 = '绿茶';document.write('drink2 = ' + drink2 + '<br />');");
	// 默认模式中, eval()在其被调用的作用域中创建的变量, 在其它作用域中可以访问, 而且它是全局变量
	document.write('drink2 = ' + drink2 + ', window.drink2 = ' + window.drink2 + '<br />');
</script>

4.11. 字符串"eval"不可用作变量:

<script type="text/javascript">
	"use strict";
	// 报错, 严格模式中, 字符串"eval"不可用作变量
	var eval = 'eval';
</script>

<script type="text/javascript">
	// 默认模式中, 字符串"eval"可以用作变量
	var eval = 'eval';
	document.write('eval = ' + eval + '<br />');
</script>

4.12. 字符串"arguments"不可用作变量:

<script type="text/javascript">
	"use strict";
	// 报错, 严格模式中, 字符串"arguments"不可用作变量
	var arguments = 'arguments';
</script>

<script type="text/javascript">
	// 默认模式中, 字符串"arguments"可以用作变量
	var arguments = 'arguments';
	document.write('arguments = ' + arguments + '<br />');
</script>

4.13. with语句是不允许的:

<script type="text/javascript">
	"use strict";
	var book1 = "Effective Java";
	// 报错, 严格模式中, with语句是不允许的
	with(book1) {
		document.write('book1 = ' + toUpperCase() + '<br />');
	}
</script>

<script type="text/javascript">
	var book2 = "Netty In Action";
	// 默认模式中, with语句是允许的
	with(book2) {
		document.write('book2 = ' + toUpperCase() + '<br />');
	}
</script>

5. 对未来的保障

5.1. 严格模式中不允许使用为未来预留的关键词。它们是:

implements
interface
let
package
private
protected
public
static
yield

6. 函数中的this(严格模式)

6.1. JavaScript严格模式不允许默认绑定。

6.2. 因此, 在函数中使用时, 在严格模式下, this是未定义的undefined。

<script type="text/javascript">
	"use strict";
	function myFn6(){
		document.write(this + '<br />'); // 输出undefined
	}
	myFn6();
</script>

7. 函数中的this(默认)

7.1. 在JavaScript函数中, 函数的拥有者默认绑定this。

7.2. 因此, 在函数中, this指的是全局对象[object Window]。

<script type="text/javascript">
	function myFn7(){
		document.write(this + '<br />'); // 输出[object Window]
	}
	myFn7();
</script>

8. 例子

8.1. 代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>严格模式</title>
	</head>
	<body>
		<script type="text/javascript">
			"use strict";
			function myFn1(){
				document.write(this + '<br />');
			}
			myFn1();

			// 报错, 严格模式中, 在不声明变量的情况下使用变量, 是不允许的
			// a = 5;

			var c = 15;
			// 报错, 严格模式中, 使用delete删除变量, 是不允许的
			// delete c;
		
			// 报错, 严格模式中, 使用delete删除函数, 是不允许的
			// delete myFn1;

			// 报错, 严格模式中, 重复使用参数名, 是不允许的
			// function myFn4(p1, p1){
			// 	document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');
			// }
			// myFn4(25, 30);

			// 报错, 严格模式中, 八进制数值是不允许的
			// document.write('e = ' + 010 + '<br />');

			// 报错, 严格模式中, 八进制转义字符是不允许的:
			// document.write('\077' + '<br />');

			var obj1 = {get Id(){return this.id;}};
			Object.defineProperty(obj1, 'id', {value: 1001, writable: false});
			// 报错, 严格模式中, 写入只读属性是不允许的
			// obj1.id = 1002;
			document.write('obj1.id = ' + obj1.id + '<br />');
			// 报错, 严格模式中, 写入只能获取的属性是不允许的
			// obj1.Id = 1003;
			document.write('obj1.Id = ' + obj1.Id + '<br />');

			// 报错, 严格模式中, 删除不可删除的属性是不允许的
			// delete Object.prototype;
			
			eval("var drink1 = '红茶';document.write('drink1 = ' + drink1 + '<br />');");
			// 报错, 严格模式中, eval()在其被调用的作用域中创建的变量, 在其它作用域中不允许
			// document.write('drink1 = ' + drink1 + ', window.drink1 = ' + window.drink1 + '<br />');

			// 报错, 严格模式中, 字符串"eval"不可用作变量
			// var eval = 'eval';

			// 报错, 严格模式中, 字符串"arguments"不可用作变量
			// var arguments = 'arguments';
		
			var book1 = "Effective Java";
			// 报错, 严格模式中, with语句是不允许的
			// with(book1) {
			// 	document.write('book1 = ' + toUpperCase() + '<br />');
			// }
		
			function myFn6(){
				document.write(this + '<br />'); // 输出undefined
			}
			myFn6();
		</script>

		<script type="text/javascript">
			function myFn2(){
				document.write(this + '<br />');
			}
			myFn2();

			function myFn3(){
				"use strict";
				document.write(this + '<br />');
			}
			myFn3();

			// 默认模式中, 在不声明变量的情况下使用变量, 成为全局变量
			b = 10;

			var d = 20;
			// 默认模式中, 使用delete删除变量, 没有任何影响
			delete d;
			document.write('d = ' + d + '<br />');

			// 默认模式中, 使用delete删除函数, 没有任何影响
			delete myFn2;
			myFn2();

			// 默认模式中, 重复使用参数名, 参数值是最后一个实参的值
			function myFn5(p1, p1){
				document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');
			}
			myFn5(35, 40);

			// 默认模式中, 八进制数值是允许的
			document.write('f = ' + 020 + '<br />');

			// 默认模式中, 八进制转义字符是允许的
			document.write('\077' + '<br />');

			var obj2 = {get Id(){return this.id;}};
			Object.defineProperty(obj2, 'id', {value: 10001, writable: false});
			// 默认模式中, 写入只读属性, 不会报错, 但也不会赋值
			obj2.id = 10002;
			document.write('obj2.id = ' + obj2.id + '<br />');
			// 默认模式中, 写入只能获取的属性, 不会报错, 但也不会赋值
			obj2.Id = 10003;
			document.write('obj2.Id = ' + obj2.Id + '<br />');

			// 默认模式中, 删除不可删除的属性, 没有任何影响
			delete Object.prototype;
			document.write('Object.prototype = ' + Object.prototype + '<br />');

			eval("var drink2 = '绿茶';document.write('drink2 = ' + drink2 + '<br />');");
			// 默认模式中, eval()在其被调用的作用域中创建的变量, 在其它作用域中可以访问, 而且它是全局变量
			document.write('drink2 = ' + drink2 + ', window.drink2 = ' + window.drink2 + '<br />');

			// 默认模式中, 字符串"eval"可以用作变量
			var eval = 'eval';
			document.write('eval = ' + eval + '<br />');

			// 默认模式中, 字符串"arguments"可以用作变量
			var arguments = 'arguments';
			document.write('arguments = ' + arguments + '<br />');

			var book2 = "Netty In Action";
			// 默认模式中, with语句是允许的
			with(book2) {
				document.write('book2 = ' + toUpperCase() + '<br />');
			}

			function myFn7(){
				document.write(this + '<br />'); // 输出[object Window]
			}
			myFn7();
		</script>
	</body>
</html>

8.2. 效果图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值