Skip to content

严格模式

早期的 JS 有很多设计缺陷,严格模式在 ES5 引入,主要目的是在写代码时就尽可能避免一些怪异的行为,有着更多的规则和报错场景,让 JS 更安全。

启用方法

在脚本的第一行加入use strict or 在函数体的第一行,加入use strict

更多的报错场景

有些行为,再非严格模式下,就会静默失败,不会报错,开启严格模式,这些行为就会显式报错。

只读属性不可写

比如字符串的length属性,对象的只读属性,如果写入就会报错,中断代码执行

js
'use strict'
// const a = '123'
// a.length = 2 // 报错 TypeError

const obj = {}
Object.defineProperty(obj, 'k', {
    value: 2,
    writable: false
})
obj.k = '3' // 报错 TypeError
console.log(obj.k)

只设置了 getter 的属性不可赋值

不赘述...

不可拓展的对象新增属性报错

不赘述...

函数参数不能重名

在非严格模式下,参数可以重名,比如3个a,那么,最终 a 的值就是第三个参数。
在严格模式下,定义了就报错。

js
'use strict'
function f(a,a,a){ // SyntaxError
    console.log(a) 
}

f(1,2,3)

增强的安全措施

全局变量必须声明

非严格模式下,直接给一个莫名奇妙的变量赋值,默认这个变量是全局变量。 严格模式要求必须声明。

禁止 this 指向全局对象

构造函数忘记用 new 时,里边的this会指向全局,带来意想不到的全局变量 这种情况在严格模式下 thisundefined

js
// 正常模式
function f() {
  console.log(this === window);
}
f() // true

// 严格模式
function f() {
  'use strict';
  console.log(this === undefined);
}
f() // true

禁止使用 fn.callee、fn.caller

函数内部不能拿到调用栈。

删除变量严格

严格模式下, delete操作符只能用于删除对象可配置属性

js
'use strict'

var x;
delete x; // SyntaxError


var obj = Object.create(null, {
    x: {
        value: 1,
        configurable: false
    }
});
delete obj.x; // TypeError

静态绑定

JS 的特点就是允许“动态绑定”,即某些属性和方法到底属于哪一个对象,不是在编译时确定的,而是在运行时确定的。严格模式对动态绑定做了一些限制。

禁用 with

with 语句扩展一个语句的作用域链, 已被标准弃用。

eval 作用域

在全局作用域和函数作用域之外,严格模式创设了第三种作用域:eval作用域。

arguments 不在函数内部追踪变化

I think it`s 太冷了 bro.

像新版本过渡

非函数代码块不得声明函数

函数只允许在全局作用域或函数作用域下声明。

新增保留字

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield