龙空技术网

JavaScript高级程序员秘笈:JS严格模式的七大问题

IT豆豆 1266

前言:

眼前小伙伴们对“js调用打印机静默打印”大约比较注意,咱们都需要剖析一些“js调用打印机静默打印”的相关文章。那么小编同时在网络上搜集了一些对于“js调用打印机静默打印””的相关资讯,希望我们能喜欢,大家快快来学习一下吧!

严格模式不仅仅是一个子集:它故意地具有与正常代码不同的语义。不支持严格模式的浏览器将会执行与支持严格模式的浏览器不同行为的严格模式代码。所以不要依靠严格模式,在没有特性测试来支持严格模式的相关方面。严格模式代码和非严格模式代码可以共存,因此脚本可以逐步选择严格模式。

严格模式对正常的 JavaScript语义做了一些更改。

首先,严格模式消除了一些 JavaScript的静默错误,通过改变它们来抛出错误。

其次,严格的模式修复了 JavaScript引擎难以执行优化的错误:有时候,严格模式代码可以比非严格模式的相同的代码运行得更快。

第三,严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。

编者注:有时,你会看到标准的,非严格的模式,被称为“马虎模式/稀松模式/懒散模式”。这不是一个官方术语,但你应该意识到这一点,以防万一。

开启严格模式

严格模式可以应用到整个script标签或个别函数中。不要在封闭大括弧 {} 内这样做;在这样的上下文中这么做是没有效果的。在eval 代码,Function 代码,事件处理属性,传入 setTimeout方法的字符串和包含整个脚本的块中开启严格模式会如预期一样工作。

为某个script标签开启严格模式

为整个script标签开启严格模式, 需要在所有语句之前放一个特定语句 "use strict"; (或 'use strict';)

这种语法存在陷阱,有一个大型网站已经被它坑倒了:不能盲目的合并冲突代码。试想合并一个严格模式的脚本和一个非严格模式的脚本:合并后的脚本代码看起来是严格模式。反之亦然:非严格合并严格看起来是非严格的。合并均为严格模式的脚本或均为非严格模式的都没问题,只有在合并严格模式与非严格模式有可能有问题。建议按一个个函数去开启严格模式(至少在学习的过渡期要这样做).

您也可以将整个脚本的内容用一个函数包括起来,然后在这个外部函数中使用严格模式。这样做就可以消除合并的问题,但是这就意味着您必须要在函数作用域外声明一个全局变量。

为某个函数开启严格模式

同样的,要给某个函数开启严格模式,得把 "use strict"; (或 'use strict'; )声明一字不漏地放在函数体所有语句之前。

严格模式有哪些不同

严格模式同时改变了语法及运行时行为。变化通常分为这几类:将问题直接转化为错误(如语法错误或运行时错误), 简化了如何为给定名称的特定变量计算,简化了 eval 以及 arguments, 将写"安全“JavaScript的步骤变得更简单,以及改变了预测未来ECMAScript行为的方式。

将拼写错转成异常

在严格模式下, 先前被接受的拼写错误将会被认为是异常. JavaScript被设计为能使新人开发者更易于上手, 所以有时候会给本来错误操作赋予新的不报错误的语义(non-error semantics). 有时候这可以解决当前的问题, 但有时候却会给以后留下更大的问题. 严格模式则把这些失误当成错误, 以便可以发现并立即将其改正.

首先,严格模式下无法再意外创建全局变量。在普通的JavaScript里面给一个拼写错误的变量名赋值会使全局对象新增一个属性并继续“工作”(尽管后面可能出错:在现在的JavaScript中有可能)。严格模式中意外创建全局变量被抛出错误替代:

其次, 严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操抛出异常. 例如, NaN 是一个不可写的全局变量. 在正常模式下, 给 NaN 赋值不会产生任何作用; 开发者也不会受到任何错误反馈. 但在严格模式下, 给 NaN 赋值会抛出一个异常. 任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值, 给只读属性(getter-only)赋值赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常:

第三, 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):

第四,在Gecko版本34之前,严格模式要求一个对象内的所有属性名在对象内必须唯一。正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码要去改变属性值而不是修改最后一个重名属性的时候,复制这个对象就产生一连串的bug。在严格模式下,重名属性被认为是语法错误(编者注:这个问题在ECMAScript6中已经不复存在):

第五, 严格模式要求函数的参数名唯一. 在正常模式下, 最后一个重名参数名会掩盖之前的重名参数. 之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问. 然而, 这种隐藏毫无意义而且可能是意料之外的 (比如它可能本来是打错了), 所以在严格模式下重名参数被认为是语法错误:

第六, 严格模式禁止八进制数字语法. ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法: 0644 === 420 还有 "\045" === "%".在ECMAScript 6中支持为一个数字加"0o"的前缀来表示八进制数.

var a = 0o10; // ES6: 八进制

有些新手开发者认为数字的前导零没有语法意义, 所以他们会用作对齐措施 — 但其实这会改变数字的意义! 八进制语法很少有用并且可能会错误使用, 所以严格模式下八进制语法会引起语法错误:

第七,ECMAScript 6中的严格模式禁止设置primitive值的属性.不采用严格模式,设置属性将会简单忽略(no-op),采用严格模式,将抛出TypeError错误

标签: #js调用打印机静默打印