随着WebApp突飞猛进的发展,Javascript写的WebApp规模越来越庞大,比如典型的代表产品腾讯WebQQ、HTML5游戏等等,Javascript越来越需要大量的开发人员多多人协作开发。同时HTML5、CSS3等新技术和NodeJs项目的高速发展,这几年JavaScript语言借着各种新API陆续被运用到从移动设备到服务器的多个”新领域”中。
但JavaScript语言自身由于ECMAScript第四版被放弃而一直没有多少改进。和借HTML5之名过度宣传的各种新API相比,语法层面通过严格模式(Strict Mode)进行的改进几乎可以用不为人知来形容。学习了解严格模式之后,就算不马上进行实践,也会让我们对JavaScript中坏气味的一方面有更清晰的认识,从而帮助我们写出更好的代码。
下面的内容翻译自It’s time to start using JavaScript strict mode,作者Nicholas C.Zakas参与了YUI框架的开发,并撰写了多本前端技术书籍,在我看过关于JavaScript严格模式的入门介绍文章中,这篇是写得最好的。
ECMAScript5中引入的严格模式,通过让JavaScript运行环境对一些开发过程中最常见和不易发现的错误做出和当前不同的处理,来让开发者拥有一个”更好”的JavaScript语言。很长一段时间内,由于只有Firefox支持严格模式,我曾对严格模式表示怀疑。但到了今天,所有主流的浏览器都在他们的最新版本中支持了严格模式(包括IE10,Opera12和Android4,IOS5)是时候开始使用严格模式了。
严格模式能起到什么作用?
严格模式为JavaScript引入了很多变化,我把他们分为两类(明显的和细微的)。细微改进的目标是修复当前JavaScript中的一些细节问题,对于这些问题我不在这里进行深入介绍;如果你有兴趣,请阅读Dmitry Soshnikov撰写的精彩文档ECMA-262-5 in Detail Chapter 2 Strict Mode。 我在这里主要介绍严格模式引入的明显变化,那些在你使用严格模式前应该知道的概念和那些对你帮助最大的改变。
在开始学习具体特性前,请记住严格模式的一大目标是让你能更快更方便的调试。运行环境在发现问题时显性的抛出错误比默不做声的失败或怪异行事(未开启严格模式的JavaScript运行环境经常这样)要好。严格模式会抛出更多错误,但这是好事,因为这些错误会唤起你注意并修复很多以前很难被发现的潜在问题。
去除with关键词
首先,严格模式中去除了with语句,包含with语句的代码在严格模式中会抛出异常。所以使用严格模式的第一步:确保你的代码中没有使用with。
// 在严格模式中以下JavaScript代码会抛出错误 with (location) { alert(href); }
防止意外为全局变量赋值
其次,局部变量在赋值前必须先进行申明。在启用严格模式之前,为一个未申明的局部变量复制时会自动创建一个同名全局变量。这是Javacript程序中最容易出现的错误之一, 在严格模式中尝试这么做时会有显性的异常抛出。
// 严格模式下会抛出异常 (function() { someUndeclaredVar = "foo"; }());
函数中的this不再默认指向全局
严格模式中另一个重要的变化是函数中未被定义或为空( null or undefined)的this不在默认指向全局环境(global)。这会造成一些依赖函数中默认this行为的代码执行出错,例如:
window.color = "red"; function sayColor() { alert(this.color); } // 在strict模式中会报错, 如果不在严格模式中则提示 “red" sayColor(); // 在strict模式中会报错, 如果不在严格模式中则提示 “red" sayColor.call(null);
this在被赋值之前会一直保持为undefined,这意味着当一个构造函数在执行时,如果之前没有明确的new关键词,会抛出异常。
function Person(name) { this.name = name; } //在严格模式中会报错 var me = Person("Nicholas");
在上面的代码中,Person构造函数运行时因为之前没有new,函数中的this会保留为undefined, 由于你不能为undefined设置属性,上面的代码会抛出错误。 在非strict模式环境中,没有被复制的this会默认指向window全局变量,运行的结果将是意外的为window全局变量设置name属性。
防止重名
当编写大量代码时,对象属性和函数参数很容易一不小心被设置成一个重复的名字。严格模式在这种情况下会显性的抛出错误
//重复的变量名,在严格模式下会报错 function doSomething(value1, value2, value1) { //code } //重复的对象属性名,在严格模式下会报错: var object = { foo: "bar", foo: "baz" };
以上的代码在严格模式中都会被认为是语法错误而在执行前就让你能得到提示。
安全的 eval()
虽然eval()语句最终没有被移除,但在严格模式中仍然对它进行了一些改进。最大的改变是在eval()中执行的变量和函数申明不会直接在当前作用域中创建相应变量或函数,例如:
(function() { eval("var x = 10;"); // 非严格模式中,alert 10 // 严格模式中则因x未被定义而抛出异常, alert(x); }());
任何在eval()执行过程中创建的变量或者函数保留在eval()中。但你能明确的从eval()语句的返回值来获取eval()中的执行结果,例如:
(function() { var result = eval("var x = 10, y = 20; x + y"); // 在strict或非strict模式中都能正确的运行余下的语句.(resulst为30) alert(result); }());
对只读属性修改时抛出异常
ECMAScript5中还引入为对象的特定属性设为只读,或让整个对象不可修改的能力。 但在非严格模式中,尝试修改一个只读属性只会默不做声的失败。 在你和一些浏览器原生API打交道过程中,你很可能遇到这种情况。严格模式会在这种情况下明确的抛出异常,提醒你修改这个属性是不被允许的。
var person = {}; Object.defineProperty(person, "name" { writable: false, value: "Nicholas" }); // 在非严格模式时,沉默的失败,在严格模式则抛出异常. person.name = "John";
上面的例子中,name属性被设为只读,非严格模式中执行对name属性的修改不会引发报错,但修改不会成功。但严格模式则会明确的抛出异常。
NOTE: 强烈建议你在使用任何ECMAScript属性特性指定时开启严格模式。
如何使用?
在现代浏览器中开启严格模式非常容易,只需要在JavaScript代码中出现以下指令即可
"use strict";
虽然看上去上面的代码仅仅只是未赋予某个变量的字符串,它实际上起到指示JavaScript引擎切换到严格模式的作用(不支持严格模式的浏览器会忽略以上代码,不会对后续的执行产生任何影响)。虽然你能把这个指令作用到全局或某个函数中,但这里还是要提醒,不要在全局环境下启用严格模式。
// 请不要这么使用 "use strict"; function doSomething() { // 这部分代码会运行于严格模式 } function doSomethingElse() { // 这部分代码也会运行于严格模式 }
虽然上面的代码看起来不算一个大问题。但当你不负责维护页面中引入的全部代码时,这样使用strict模式会让你面临由于第三方代码没有为严格模式做好准备而引发的问题。
因此,最好把开启严格模式的指令作用于函数中,例如:
function doSomething() { "use strict"; // 这个函数中的代码将会运行于严格模式 } function doSomethingElse() { // 这个函数中代码不会运行于严格模式 }
如果你想让严格模式在不止一个函数中开启,请使用立即执行函数表达式 (immediately-invoked function expression ,IIFE):
(function() { "use strict"; function doSomething() { // 这个函数运行于严格模式 } function doSomethingElse() { // 这个函数同样运行于严格模式 } }());
结论
我强烈建议你从现在开始就启用JavaScript严格模式,它能帮你发现代码中未曾注意到的错误。不要在全局环境中启用,但你能尽量多的使用IIFE(立即执行函数表达式)来把严格模式作用到多个函数范围内。一开始,你会遇到之前未曾碰到过的错误提示,这是正常的。当启用严格模式后,请确保在支持的浏览器中做了测试,以发现新的潜在问题。一定不要仅仅在代码中添加一行”use strict”就假定余下的代码能正常工作。最后,请在严格模式下开始编写更好的代码。
注:
这里有各款浏览器对严格模式支持情况的一个汇总。
可以在这个页面对当前浏览器的严格模式支持度进行测试。
发表评论
-
基于脚本的动画的计时控制(“requestAnimationFrame”)(转载)
2014-03-04 19:12 1035Internet Explorer 10 和使 ... -
IE11开发人员工具:UI响应工具详解
2014-02-27 18:33 938我讨厌debug,相信也没多少开发者会喜欢。但是当代码出 ... -
IE11开发人员工具:内存分析工具详解
2014-02-27 18:32 1453上篇我们跟大家介绍 ... -
E6与location.hash和Ajax历史记录 (转载)
2014-02-26 12:23 557为了在IE6中改变hash来保留历史记录实现ajax的前进 ... -
MIME Types(转载)
2013-12-31 10:20 648MIME Types - Complete List ... -
iframe历史记录问题(转载)
2013-10-17 10:21 1339在做页面统计的时候 ... -
前端类库精选(转)
2013-05-11 00:57 0优秀的前端类库,自己平时遇见了,这里Mark一下。 1、m ... -
10个chrome console实用小技巧(转)
2013-05-09 10:56 10671. 基本输出 让我们先从最常见的console.l ... -
CSS3那些不为人知的高级属性(转)
2013-04-19 13:35 951原文:CSS的未来:一些 ... -
JavaScript 时间、格式、转换及Date对象总结(转)
2013-04-10 14:49 717悲剧的遇到问题,从前台得到时间,“Tue Jan 29 16 ... -
如何制作一个可及性强(accessible)的网页弹框(转载)
2013-04-02 16:18 807英文原文:Making an accessib ... -
JavaScript MVC js也mvc(转载)
2013-03-16 23:59 690JavaScript MVC 中文:http://blog ... -
SUBLIME TEXT 2 设置文件详解
2012-12-27 11:21 1059Sublime Text 2是那种让人会一眼就爱上的编辑 ... -
两个按位非操作与Math.floor操作(译)
2012-12-10 18:17 954位操作符在我们编码过程中是容易被遗忘的,可能更多的源于我们 ... -
img中src为空的影响
2012-11-26 23:32 0这是我们经常能遇到的代码,可以直接用html标签或者Java ... -
IE6下position定位子元素溢出,父元素被撑开的解决思路。(转)
2012-11-13 18:04 1644在一些被常规的页面布局当中,我们常常需要通过positi ... -
chrome developer tool 调试技巧(转)
2012-11-12 13:16 868这篇文章是根据目前 chrome 稳定版(19.0.10 ... -
你清楚jquery是如何清除ajax缓存的吗?(转)
2012-11-11 11:19 1055大家都知道万恶的IE在ajax中往往只读取第一次ajax ... -
Javascript基础
2012-11-10 23:25 0原文:http://bonsaiden.githu ... -
高质量JavaScript精品库集合 In JavaScript,资源工具(转)
2012-11-10 10:27 771编辑器 1、Code Mirror 又一款“Onli ...
相关推荐
在JavaScript中,**严格模式**(strict mode)是ECMAScript 5引入的一种新特性,旨在改善语言的一些不足,提高代码质量和安全性,以及为未来的JavaScript版本铺平道路。严格模式的启用不仅能够帮助开发者避免一些...
"strict mode"(严格模式)是JavaScript中一个非常重要的概念,它改变了代码的执行方式,使得代码更加安全、可靠,并且有助于发现潜在的问题。在前端开源库中启用严格模式,可以显著提升代码质量和维护性。 严格...
主要介绍了在JavaScript中使用严格模式(Strict Mode),除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。,需要的朋友可以...
JavaScript的严格模式(strict mode)是ECMA-262 Edition 5引入的一种新的脚本执行方式,旨在对JavaScript的语言规则作出更严格的限制,以帮助开发者编写更清晰、更规范的代码。在严格模式下,一些在普通模式(非...
- **模块开发**:在开发JavaScript模块时,使用严格模式可以避免模块间的命名冲突。 - **大型项目**:在大型项目中,启用严格模式有助于保持代码质量的一致性,减少潜在的错误。 - **教育和培训**:教授严格模式可以...
使用Knockout,开发者能够更容易地创建具有动态变化的用户界面,提升开发效率。 在MVVM模式中,模型(Model)是数据的抽象,视图(View)是用户界面的抽象,而视图模型(ViewModel)作为模型和视图的桥梁,负责处理...
在前端开发领域,"严格模式"(Strict Mode)是一个重要的概念,它主要应用于JavaScript代码中。严格模式是一种特殊的运行模式,旨在提供更安全、更严格的编程环境,帮助开发者避免一些常见的错误并提升代码质量。在...
严格模式 在您的包裹中启用严格模式 安装 用做 npm install strict-mode --save-dev NOTA BENE你可能要安装严格的模式作为发展的依赖,见。 用法 请注意,该软件包旨在用于服务器端。 如果与使用,则为 。 假设...
JavaScript 严格模式(strict mode)即在严格的条件下运行。 使用 “use strict” 指令 “use strict” 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。 它不是一条语句,但是是一个字面量表达式,在 JavaScript ...
其中之一便是“严格模式”(strict mode),这使得JavaScript的语法变得更加严格,旨在消除JavaScript中一些不合理的、不便于维护的特性。严格模式下,原先一些常见的导致错误的代码将不再被允许执行,其中包括强制...
ECMAScript 5 引入了严格模式(Strict Mode),这是一种更加严谨的执行上下文。它可以帮助开发者写出更加健壮、易于维护的代码,并且可以在一定程度上提高程序的执行效率。严格模式会进行更多的类型检查,并禁止某些...
严格模式(Strict Mode):讲解了ECMAScript 5引入的严格模式,用于编写更安全、更规范的JavaScript代码。 C. JavaScript库(JavaScript Libraries):可能列举并分析了一些流行的JavaScript库,例如jQuery、...
ECMAScript 5严格模式(Strict Mode)是JavaScript的一个重要特性,它旨在增强代码的可靠性和安全性。严格模式通过对语法的限制和抛出更多异常,帮助开发者编写更规范的代码,减少潜在的错误。 启用严格模式主要有...
JavaScript设计之初存在许多不严谨的地方,比如未声明的变量可以直接赋值使用(例如`n=100`),这在程序中可能会引入难以预料的错误和安全隐患。严格模式(Strict Mode)的引入,就是为了规避这类问题。它通过抛出更...
* 使用 strict mode 来启用严格模式,以提高代码的安全性和可读性。 * 了解 JavaScript 中的特殊关键字和保留字,以避免命名冲突。 JavaScript 是一种功能强大且灵活的语言,用于开发各种 web 应用程序和桌面应用...