随着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 949Internet Explorer 10 和使 ... -
IE11开发人员工具:UI响应工具详解
2014-02-27 18:33 891我讨厌debug,相信也没多少开发者会喜欢。但是当代码出 ... -
IE11开发人员工具:内存分析工具详解
2014-02-27 18:32 1381上篇我们跟大家介绍 ... -
E6与location.hash和Ajax历史记录 (转载)
2014-02-26 12:23 520为了在IE6中改变hash来保留历史记录实现ajax的前进 ... -
MIME Types(转载)
2013-12-31 10:20 605MIME Types - Complete List ... -
iframe历史记录问题(转载)
2013-10-17 10:21 1255在做页面统计的时候 ... -
前端类库精选(转)
2013-05-11 00:57 0优秀的前端类库,自己平时遇见了,这里Mark一下。 1、m ... -
10个chrome console实用小技巧(转)
2013-05-09 10:56 10251. 基本输出 让我们先从最常见的console.l ... -
CSS3那些不为人知的高级属性(转)
2013-04-19 13:35 904原文:CSS的未来:一些 ... -
JavaScript 时间、格式、转换及Date对象总结(转)
2013-04-10 14:49 684悲剧的遇到问题,从前台得到时间,“Tue Jan 29 16 ... -
如何制作一个可及性强(accessible)的网页弹框(转载)
2013-04-02 16:18 783英文原文:Making an accessib ... -
JavaScript MVC js也mvc(转载)
2013-03-16 23:59 666JavaScript MVC 中文:http://blog ... -
SUBLIME TEXT 2 设置文件详解
2012-12-27 11:21 1021Sublime Text 2是那种让人会一眼就爱上的编辑 ... -
两个按位非操作与Math.floor操作(译)
2012-12-10 18:17 920位操作符在我们编码过程中是容易被遗忘的,可能更多的源于我们 ... -
img中src为空的影响
2012-11-26 23:32 0这是我们经常能遇到的代码,可以直接用html标签或者Java ... -
IE6下position定位子元素溢出,父元素被撑开的解决思路。(转)
2012-11-13 18:04 1608在一些被常规的页面布局当中,我们常常需要通过positi ... -
chrome developer tool 调试技巧(转)
2012-11-12 13:16 815这篇文章是根据目前 chrome 稳定版(19.0.10 ... -
你清楚jquery是如何清除ajax缓存的吗?(转)
2012-11-11 11:19 1027大家都知道万恶的IE在ajax中往往只读取第一次ajax ... -
Javascript基础
2012-11-10 23:25 0原文:http://bonsaiden.githu ... -
高质量JavaScript精品库集合 In JavaScript,资源工具(转)
2012-11-10 10:27 722编辑器 1、Code Mirror 又一款“Onli ...
相关推荐
主要介绍了Javascript的严格模式strict mode详细介绍,重点介绍了严格模式的使用方法及使用strict mode后对javascript语法上带来的改变,需要的朋友可以参考下
主要介绍了在JavaScript中使用严格模式(Strict Mode),除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。,需要的朋友可以...
Strict mode是JavaScript1.8.5引进的技术,但还没有浏览器确实可靠的实现了严格模式,所以使用时要小心并且多测试。Strict mode可以应用于整个脚本,也可以适合于单个函数。
Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化。
JavaScript 严格模式(strict mode)即在严格的条件下运行。 使用 “use strict” 指令 “use strict” 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。 它不是一条语句,但是是一个字面量表达式,在 JavaScript ...
严格模式 在您的包裹中启用严格模式 安装 用做 npm install strict-mode --save-dev NOTA BENE你可能要安装严格的模式作为发展的依赖,见。 用法 请注意,该软件包旨在用于服务器端。 如果与使用,则为 。 假设...
2009年12月,...ECMAScript 5在目标上没有那么雄心勃勃,除去新增了对JSON的支持和反射的更全面的控制,一项重要改进就是引入“严格模式”(strict mode)。在此模式下,ECMAScript的语法变得更严格,使得原先
除了正常运行模式,ECMAscript 5添加了第二种运行模式:”严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。 设立”严格模式”的目的,主要有以下几个: a - 消除Javascript...
除了正常运行模式,ECMAscript 5添加了第二种运行模式:“严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。 设立”严格模式”的目的,主要有以下几个: 消除Javascript语法的...
JavaScript自定数量动态层操作 根据提供参数,自动建立DIV集合,并可以任意交换DIV对象位置
引入Strict Mode目的是允许开发人员能够选择“更好”的Javascript版本,这个版本能用不同的方式处理那些普遍而又臭名昭著的错误。目前所有的主流浏览器的最新版本——包括IE10与Opera12——都支持严格模式。关于严格...
上一篇文章分享了《带你学习Javascript中的函数进阶(一)》,今天继续学习javascript的函数进阶的内容。...JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性Javascript
那么,为什么我们能删除一个对象的属性: var x = { a: 1 }; delete x.a; // true x.a; // undefined 但却不能删除一个变量: var x = 1;... 每一个属性拥有零至多个如内部属性——*ReadOnly,DontEnum,DontDelete...
我们平时写的JavaScript代码一般都运行在正常模式中的,除了正常运行模式,ECMAscript 5添加了第二种运行模式:”严格模式”(strict mode)。看名字就知道,这种模式会让JavaScript在更严格的环境中运行。 包括IE ...
例如,如果您尝试在Node.js 4中使用let语句,那么如果JavaScript文件没有“ use strict”,则会看到此错误: SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside ...
除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。下面这篇文章主要给大家介绍了在JavaScript严格模式下关于this的几种指向的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧...
常见错误一:对于this关键词的不正确引用 常见错误二:传统编程语言的生命周期误区 常见错误三:内在泄露 常见错误四:比较运算符 常见错误五:低效的DOM操作 ...常见错误十:忽略“strict mode”的作用