JS 中的严格模式与非严格模式

JavaScript015

JS 中的严格模式与非严格模式,第1张

严格模式是一种将更好的错误检查引入代码中的方法。 在使用严格模式时,无法使用隐式声明的变量、将值赋给只读属性或将属性添加到不可扩展的对象等

1、  严格模式的目的

1) 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为

2)消除代码运行的一些不安全之处,保证代码运行的安全

3) 提高编译器效率,增加运行速度

4) 为未来新版本的Javascript做好铺垫

 2、声明严格模式

可以通过在文件、程序或函数的开头添加 "use strict" 来声明严格模式。 此类声明称作“指令序言”。 严格模式声明的范围取决于其上下文。 如果在全局上下文(函数的范围之外)中声明严格模式,则程序中的所有代码都处于严格模式。如果在函数中声明严格模式,则函数中的所有代码都处于严格模式。

例如,在以下示例中,所有代码都处于严格模式,并且函数外部的变量声明会导致出现语法错误“严格模式下未定义变量”

"use strict"

function testFunction(){

    var testvar = 4

    return testvar

}

// This causes a syntax error.

testvar = 5

在以下示例中,仅 testFunction 中的代码处于严格模式。 函数外部的变量声明不会导致语法错误,但函数内部的声明会导致语法错误

function testFunction(){

    "use strict"

    // This causes a syntax error.

    testvar = 4

    return testvar

}

testvar = 5

非严格模式下,以下调用方式中, this 绑定为全局对象 window ,

而在严格模式下, this 绑定为 undefined 。

值得注意是的,只有 this 处于严格模式中,才会绑定为 undefined ,

与 f 被调用的位置是否处于严格模式无关。

可见 new 对 this 的影响比 bind 优先级要高,

g 虽然通过 bind 绑定了 this 指向的对象为 {a:1} ,

但是使用 new g 调用的时候, this 仍然指向以 f 为构造函数的实例。

值得注意的有两点,

(1) bind 之后, g.prototype 为 undefined 。

(2) new g 返回的对象 obj ,使用 instanceof 判断 f 和 g 都为 true ,

原因就在于, V instanceof target 首先会先用 target[Symbol.hasInstance](V) 来判断,

然后再判断, target.prototype 是否在 V 的原型链上,参考 ECMAScript Language Specification

但是 bind 的柯里化作用还是有用的,

使用 call 或者 apply ,将 this 绑定为 null 或 undefined 并不会凑效,

此时, this 将绑定为全局对象。

然而,在严格模式下, this 将绑定为 null 或 undefined ,

值得一提的是,在非严格模式下, f.call(1)会自动将 1 包装成 new Number(1) ,

然后 this 指向的是这个包装对象。

而在严格模式下, f.call(1)会将 this 绑定为 1 。

b={} 相当于 b=new Object ,因此, b 是 Object 构造函数的实例。

而 Object.create(null) 会创建一个空对象,它没有原型。

注意, Object.create(undefined)会报错,

赋值表达式的返回值是函数的引用,因此相当于 f() ,

而不是 obj1.f() ,也不是 obj2.f() 。

你不知道的JavaScript(上卷)

严格模式声明:“use strict”

1、禁止变量未声明就赋值

2、限制动态绑定(属性和方法归属哪个对象在编译阶段就要确定)

1)禁止使用with

2)创建eval作用域,eval内声明的变量外部访问不到

3、增强的安全措施

1)禁止this关键字指向全局对象

2)禁止在函数内部遍历调用栈(函数内访问functionName.caller/functionName.arguments均报错)

4、禁止删除变量(只有configurable设置为true的对象属性才能被删除)

5、对只读属性赋值将会报错

6、重名错误

1)函数参数不能重名

7、禁止以零(0)开头的8进制表示法,支持数字0加字母o:“0o”为前缀表示八进制数

8、arguments的限制

1)arguments本身不能被赋值 ,但是arguments[x]仍然可以

2)arguments不再追踪参数的变化,在函数内改变参数值,arguments依然指向旧值

3)禁止使用arguments.callee,匿名函数无法调用自己了

9、函数必须在顶层声明

10、不允许使用以下保留字做变量名

1)implements

2)interface

3)let

4)package

5)private

6)protected

7)public

8)static

9)yield