JavaScript起点(严格模式深度了解)


Posted in Javascript onJanuary 28, 2013

严格模式(Strict Mode)是ECMAScript5新增的功能。ECMAScript5虽然可以向后兼容ECMAScript3,但如果使用严格模式,哪些ECMAScript5“不在建议使用”的ECMAScript3语法功能将会被全部进制,如果出现就会抛出一行。引入Strict Mode目的是允许开发人员能够选择“更好”的Javascript版本,这个版本能用不同的方式处理那些普遍而又臭名昭著的错误。目前所有的主流浏览器的最新版本——包括IE10与Opera12——都支持严格模式。关于严格模式的大多数信息都可以在《ES5规范》[PDF]的第223页找到。

如何启用严格模式
可以在全局范围内使用严格模式,也可以在一个函数范围内使用严格模式。如果要再全局范围内启用严格模式,只需要在程序的第一行使用代码即可:

'use strict';

在函数的内部启用严格模式,只需要在函数体内第一行使用代码即可:
function imStrict(){ 
'use strict'; 

// ... 其他代码 ... 
}

启用严格模式的语句只是一段普通的字符串“use strict”,没有任何新语法。这意味着不会对就旧式浏览器造成任何负面影响,因此可以大胆使用。

在函数内部启用严格模式的一个实际应用是,把整个Javascript类库定义在严格模式的函数内部,这样就可以不影响外部的代码:

(function(){ 
"use strict"; 

// Define your library strictly... 
})();

严格模式带来了什么?
在开始介绍特殊特性之前,你需要记住,严格模式的目标之一是允许更快地调试错误。帮助开发者调试的最佳途径是当确定的问题发生时抛出相应的错误(throw errors when certain patterns occur),而不是悄无声息地失败或者表现出奇怪的行为(这正是如今不在严格模式下的Javascript做的)。严格模式下的代码抛出更多的错误信 息,这是好事,因为它能帮助开发者很快注意到一些必须立即解决的问题。

去除with语句(Eliminates with)
首先,严格模式去除了with语句。当with语句出现在严格模式中时,它会被认为是非法的Javascript语句并抛出语法错误。所以,使用严格模式的第一步就是确保你没有在使用with。

// 在严格模式中将导致语法错误 
with(location){ 
alert(href); 
}

防止意外的全局变量(Prevents accidental globals)
第二点是,变量在赋值之前必须声明。在非严格模式下,给一个未声明的变量赋值将自动生成一个该名字的全局变量。这是Javascript中最普遍的错误之一。严格模式中,这样做将抛出一个错误。
// 严格模式中抛出一个错误 
(function(){ 
someUndeclaredVar ="foo"; 
}());

取消this值的强制转换(Eliminates this coercion)
另一个重要的变化是,当this值为null或undefined时,不会再将其强制转换为全局对象。也就是说,this保留了它的原始值,也因此可能会导致一些依赖于强制转换的代码发生错误。例如:
window.color ="red"; 
function sayColor(){ 
// 严格模式下,this不会指向window 
alert(this.color); 
} 
// 以下两种情况,在严格模式下都抛出错误 
sayColor(); 
sayColor.call(null);

根本而言,this值必须赋值,否则将保留undefined值。这意味着调用构造函数时若漏掉了new关键字也会导致错误:
functionPerson(name){ 
this.name = name; 
} 
// 严格模式下导致错误 
var me =Person("Nicholas");

在这段代码里,调用Person构造函数时缺少了new关键字,此时this值为undefined。由于你不能给undefined添加属性,这段代码抛出了一个错误。在非严格模式下,this会强制转换为全局对象,因此name属性能够被正确赋值为全局变量。
拒绝重复(No duplicates)
当你做了大量的编码的时候,你很容易在对象中定义了重复的属性或者给函数定义了重复的参数名。严格模式下,这两种情况都会导致错误的发生:
// 严格模式下错误 - 重复参数 
function doSomething(value1, value2, value1){ 
//code 
} 
// 严格模式下错误 - 重复属性 
var object ={ 
foo:"bar", 
foo:"baz" 
};

这两者都是语法错误,在代码执行之前将抛出错误。
更安全的eval()(Safer eval())
eval()没有被移除,但它在严格模式下发生了一些变化。最大的改变是:在eval()语句中声明的变量以及函数不会在包含域中创建。例如:
(function(){ 
eval("var x = 10;"); 
// 非严格模式下,x为10 
// 严格模式下,x没有声明,抛出一个错误 
alert(x); 
}());

任意由eval()创建的变量或函数仍呆在eval()里。然而,你可以通过从eval()中返回一个值的方式实现值的传递:
(function(){ 
var result =eval("var x = 10, y = 20; x + y"); 
// 严格模式与非严格模式下都能正常工作(得到30) 
alert(result); 
}());

不可改变引发的错误(Errors for immutables)
ECMAScript 5 同时引入了修改属性特征的能力,例如设置一个属性为只读或者冻结整个对象的结构(freezing an entire object's structure)。在非严格模式下,试图修改一个不可变的属性时将悄无声息地失败。你可能在使用一些原生APIs的时候已经遇到这类问题。严格模式将 保证无论你在何时试图使用一种不被允许的方式修改一个对象或对象的属性时抛出错误。
var person ={}; 
Object.defineProperty(person,"name"{ 
writable:false, 
value:"Nicholas" 
}); 
// 非严格模式下将悄无声息地失败,严格模式则抛出错误 
person.name ="John";

这个例子中,name属性被设置为只读。在非严格模式下,对name的赋值将悄无声息地失败;而在严格模式下,一个错误将被抛出。

:如果你在使用ECMAScript属性能力(the ECMAScript attribute capabilities),我强烈推荐你开启严格模式。如果你在改变对象的可变性(mutability of objects),你将遇到一堆错误,而它们在非严格模式下将被安静地带过。

Javascript 相关文章推荐
Javascript Cookie读写删除操作的函数
Mar 02 Javascript
js中巧用cssText属性批量操作样式
Mar 13 Javascript
javascript插入样式实现代码
Feb 22 Javascript
jquery的冒泡事件的阻止与允许(三种实现方法)
Feb 01 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
Feb 14 Javascript
原生js实现百叶窗效果及原理介绍
Apr 12 Javascript
Node.js + Redis Sorted Set实现任务队列
Sep 19 Javascript
vue 动态修改a标签的样式的方法
Jan 18 Javascript
node上的redis调用优化示例详解
Oct 30 Javascript
JavaScript forEach中return失效问题解决方案
Jun 01 Javascript
vue.js实现h5机器人聊天(测试版)
Jul 16 Javascript
js实现弹幕墙效果
Dec 10 Javascript
一个页面元素appendchild追加到另一个页面元素的问题
Jan 27 #Javascript
JavaScript转换农历类实现及调用方法
Jan 27 #Javascript
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
Jan 27 #Javascript
Extjs中的GridPanel隐藏列会显示在menuDisabled中解决方法
Jan 27 #Javascript
jQuery ajax serialize()方法的使用以及常见问题解决
Jan 27 #Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 #Javascript
Js 冒泡事件阻止实现代码
Jan 27 #Javascript
You might like
PHP FTP操作类代码( 上传、拷贝、移动、删除文件/创建目录)
2014/05/10 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
php获取一定范围内取N个不重复的随机数
2016/05/28 PHP
laravel通用化的CURD的实现
2019/12/13 PHP
键盘 keycode的值 javascript时触发事件时很有用的要素
2009/11/02 Javascript
Jquery chosen动态设置值实例介绍
2013/08/08 Javascript
关于javascript模块加载技术的一些思考
2014/11/28 Javascript
基于jquery和svg实现超炫酷的动画特效
2014/12/09 Javascript
深入理解JavaScript系列(50):Function模式(下篇)
2015/03/04 Javascript
判断访客终端类型集锦
2015/06/05 Javascript
返回函数的JavaScript函数
2016/06/14 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
JSON与String互转的实现方法(Javascript)
2016/09/27 Javascript
bootstrap datetimepicker日期插件使用方法
2017/01/13 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
2017/09/11 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
r.js来合并压缩css文件的示例
2018/04/26 Javascript
jQuery+CSS实现的标签页效果示例【测试可用】
2018/08/14 jQuery
微信小程序页面调用自定义组件内的事件详解
2019/09/12 Javascript
如何封装Vue Element的table表格组件
2021/02/06 Vue.js
[01:35]辉夜杯战队访谈宣传片—iG.V
2015/12/25 DOTA
[40:03]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#1EHOME VS Archon
2016/03/02 DOTA
基于Django filter中用contains和icontains的区别(详解)
2017/12/12 Python
Python命令行解析模块详解
2018/02/01 Python
Python生成器常见问题及解决方案
2020/03/21 Python
python小白切忌乱用表达式
2020/05/29 Python
Pycharm Git 设置方法
2020/09/15 Python
Skyscanner台湾:全球知名的旅行比价引擎
2018/07/01 全球购物
印度排名第一的蛋糕、鲜花和礼品送货:Winni
2019/08/02 全球购物
汉米尔顿手表官网:Hamilton
2020/09/13 全球购物
公关关系专员的自我评价分享
2013/11/20 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
考研英语辞职信
2015/05/13 职场文书
八年级语文教学反思
2016/03/03 职场文书
vue3使用vuedraggable实现拖拽功能
2022/04/06 Vue.js