JS

严格模式

严格模式是采用具有限制性 Javascript 变体的一种方式,从而使代码隐式地脱离 “马虎模式/稀松模式/懒散模式“ (sloppy)模式。

严格模式的改变

  • 通过抛出错误来消除了一些原有静默错误。

  • 修复了一些导致 Javascript 引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快

  • 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法。

开启严格模式

  • 整个文件开启: 在文件所有语句之前,放一个特定语句 "use strict"; 或者 'use strict';

  • 单个函数开启:在函数体所有语句之前,放一个特定语句 "use strict"; 或者 'use strict';

不要在封闭大括号({})内这样做,在这样的上下文中这么做是没有效果的。

严格模式的具体变化

  • 将过失错误转成异常。

    • 无法再意外创建全局变量,比如,a = 1

    • 引起静默失败的赋值操作抛出异常,包括:对一个对象的只读属性进行赋值、对一个使用 getter 方法读取的属性进行赋值、对禁止扩展的对象添加新属性等。

    • 试图删除不可删除的属性时会抛出异常。

    • 一个对象内的所有属性名在对象内必须唯一。

    • 函数的参数名唯一。

    • 禁止八进制数字语法,非严格模式下,整数的第一位如果是 0,表示这是八进制数,比如 0100,但严格模式禁止这种表示法,整数第一位为 0,将报错。

    • 禁止设置原始值的属性,如,(1).prop = 'a'

  • 简化变量的使用。

    • 禁止 with 语句。

    • eval 语句会创建 eval 作用域,不会给上层函数或者全局引入一个新的变量。

    • 禁止删除声明变量。

  • 让 eval 和 arguments 变的简单。

    • eval、arguments 不能作变量名或赋值。

    • 函数的传参不会随 arguments 对象的值的改变而变化。

    • 不再支持 arguments.callee。

  • 让 JavaScript 更安全。

    JavaScript 提供了一些方法(eval、Function等),给用户编写能够被其他用户执行的 Javascript 代码。在浏览器环境下,Javascript 能够获取用户的隐私信息,因此这类 Javascript, 有部分必须在运行前转换,检查是否有访问禁用功能的权限。有些函数如果滥用,会导致运行时的检查带来相当大的性能成本。

    一些严格模式的调整,要求用户提交的 Javascript 代码是严格模式,并以特定的方式调用,大大减少了运行时检查的需要。

    • 通过 this 传递给一个函数的值不会被强制转换为一个对象。比如,call、apply、bind 方法的第一个参数是原始值时,不会自动转换为对象。

    • 禁止存取函数的 caller、arguments 属性。

      function func() {
          "use strict";
          func.caller.name
          func.arguments
      }
      
      function f1(a, b) {
          return func(a, b);
      }
      
      f1(1, 2);
      // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

      fun.caller 指向最后一个调用 fun 的函数,而且 fun.arguments 是最后一个调用时的传参。严格模式下,caller、arguments 是不可存取的。

    • 禁止存取 arguments 的 callee 属性。

      function func() {
          "use strict";
          arguments.callee
      }
      func()
      // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
  • 为未来的 ECMAScript 版本铺平道路。

    • 新增一些保留字:implements、interface、let、package、private、protected、public、static、yield。ECMAscript 第五版本身还规定了另一些保留字:class、enum、export、extends、import、super,以及各大浏览器自行增加的 const 保留字。

    • 只允许在全局作用域或函数作用域的顶层声明函数,也就是,if、for 代码块内或者其他大括号({})块内不允许声明函数。

最后,记得在支持或者不支持严格模式的浏览器中测试代码。如果只在不支持严格模式的浏览器中测试,那么在支持的浏览器中就很有可能出问题,反之亦然。

代码规范

  • 遵循严格模式。

  • 尽量使用 ES6 语法。

    • 使用 constlet 关键字声明变量。

    • 使用拓展运算符 ... 复制数组、对象。

    • 使用解构赋值。

    • 使用箭头函数。

    • 最外层统一使用单引号,有变量时,使用模板字符串 (``)。

    • 使用标准的 ES6 模块语法 importexport

    • 使用对象方法、对象属性的简写方式。

  • 使用字面量值创建对象。

  • 禁止使用保留字作为对象的键值,这样在 IE8 下不会运行

  • 避免嵌套函数中直接使用 this,建议先赋值给另一个变量,如,_this|that|self

  • 避免使用 ==!= ,尽量使用 ===!==

  • 避免在内置对象(Array、String、Date等)的原型上添加方法

  • 一次只声明一个变量

  • 常量采用大写字母,下划线连接的方式

  • 每个语句的末尾不使用分号

  • for、if 语句必需在大括号内

  • switch 语句必须带有 default 分支

  • 不加空格

    • 前缀一元运算符后

    • 后缀一元运算符前

    • 函数调用括号前

    • 函数名和 () 之间

    • 对象的属性名后

    • 数组的 [ 后和 ]

    • 对象的 { 后和 }

    • 运算符 ( 后和 )

  • 加空格

    • 二元运算符前后

    • 三元运算符 ?: 前后

    • 代码块 {

    • 关键字 else、while、catch、finally

    • 关键字 if、else、for、while、do、switch、case、try,catch、finally、with、return、typeof

    • 单行注释 // 后,若单行注释和代码同行,则 // 前也需要;多行注释 *

    • 对象的属性值前

    • for 循环:分号后留空格;前置条件如果有多个,逗号后留空格

    • 函数的参数之间

  • 空行

    • 变量声明后

    • 注释前

    • 代码块后

    • 文件最后

命名规范

采用一致的方法命名变量和函数可提高代码可预测性和可维护性。

普通变量命名

驼峰式命名:第一个单词首字母小写,后面其他单词首字母大写。

匈牙利命名:前缀字母用变量类型的缩写,其余部分用变量的英文或英文的缩写,单词第一个字母大写。

JavaScript变量起名类型
变量命名前缀
举例

Array 数组

a

aList,aGroup

Boolean 逻辑

b

bChecked,bHasLogin

Function 函数

f

fGetHtml,fInit

Integer 数字

n

nPage,nTotal

Object 对象

o

oButton,oDate

Regular Expression 正则

r

rDomain,rEmail

String 字符

s

sName,sHtml

函数命名

普通函数:fn + 动词 + 名词形式。如:fnGetVersion()

内部函数:_fn + 动词 + 名词形式,内部函数必需在函数最后定义。如: _fnGetNumber

对象方法:fn + 对象类名 + 动词 + 名词形式。如: fnAddressGetEmail()

事件响应函数:fn + 触发事件对象名 + 事件名或者模块名。如:fnDivClick()

函数方法常用的动词:

构造函数(类)命名

大驼峰式命名

其他命名

  • 作用域不大临时变量可以简写。比如:str、num、bol、obj、fun、arr。

  • 循环变量可以简写。比如:i、j、k。

  • 某些作为不允许修改值的变量认为是常量,全部字母都大写,单词以_分割。例如:COPYRIGHT、PI、AUTHOR_NAME。

API 文档(注释)

  • 编写特殊格式的代码块(即一些注释块);

  • 运行工具来解析代码和注释(工具如:JsDoc Toolkit 和 YUIDoc);

  • 发布工具解析的结果,大多数情况是采用 HTML 格式发布。

参考资料

MDN - 严格模式

最后更新于

这有帮助吗?