JavaScript高级程序设计4-严格模式

533 阅读3分钟

环境

node:v12.19.0

chrome: 86.0.4240.193

严格模式?

ECMAScript5首次引入了严格模式的概念。严格模式用于选择以更严格的条件检查JavaScript代码错误,可以应用到全局,也可以运用到函数内部。

说白了其实就是一种更严格的规则。

开启严格模式

function getName() {
    "use strict"
    a = "zs";//error
    return a;
}
getName();

使用严格模式编译指示 "use strict"开启严格模式

规则

变量

无法意外创建全局变量

function setName(val) {
  "use strict"
  myName = val; // myName is not defined
  
}

无法在变量上使用delete

  • 非严格模式下静默失败(返回false)

  • 严格模式下会报错

    function setName(val) { "use strict" let myName = val; delete myName;//SyntaxError: Delete of an unqualified identifier in strict mode. } setName('zs');

对象

严格模式倾向于在非严格模式会静默失败的情况下抛出错误,增加了开发者提前发现错误的可能性

对只读属性赋值抛出TypeError

  • 非严格模式下静默失败

    "use strict" let obj = {}; Object.defineProperty(obj,'key',{ writable:false, enumerable:true, configurable:true, value:'zs' }); obj.key = '123';

在不可配置属性上使用delete会抛出TypeError

"use strict"
let obj = {};
Object.defineProperty(obj,'key',{
    writable:true,
    enumerable:true,
    configurable:false,
    value:'zs'
});
obj.key = '123';
delete obj.key;//Cannot delete property 'key' of #<Object>

对象字面量的key必须是唯一的,不可以重复

ECMAScript 6 删除了对重名属性的这个限制,即在严格模式下重复的对象字面量属

性键不会抛出错误

函数

函数参数必须唯一

  • 非严格模式下以第二个重名参数为准,只能通过arguments访问第一个参数

  • 严格模式报错

    "use strict" function setName(val,val) { //... } setName('zd','zs');//Duplicate parameter name not allowed in this context

关于arguments

  • 非严格模式下,修改参数的值会反映到arguments,修改arguments中的属性,也会反映到参数中

    function setName(val) { console.log(arguments[0]);//12 val = 10; console.log(arguments[0]);//10 arguments[0] = 14; console.log(val);//14 } setName('12');

  • 非严格模式下 则是相互独立的

    "use strict" function setName(val) { console.log(arguments[0]);//12 val = 10; console.log(arguments[0]);//12 arguments[0] = 14; console.log(val);//10 } setName('12');

  • 不允许操作arguments.callee和arguments.caller,否则报错

    function setName() { arguments.callee; } setName();//TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

ES7增加限制,在使用剩余操作符,解构操作符,默认参数时函数内部不能使用严格模式

  • 报错 Illegal 'use strict' directive in function with non-simple parameter list

    "use strict" function setName(...reset) { "use strict" console.log(reset); } setName(1,2);

  • 不报错

    "use strict" function setName() { "use strict" } setName(1,2);

只能在脚本或函数的顶级,才能进行函数声明(测试未报错)

"use strict"
function setName() {
    if(true) {
        function getName() {
            
        }
    }
}
setName();

关于eval

image.png

测试结果

变量

  • var(非严格模式)

    function getName() { eval('var x = 2;'); console.log(x); //2 } getName();

  • let (非严格模式)

    function getName() { eval('let x = 2;'); console.log(x);//x is not defined } getName();

  • 严格模式下无论是var 还是let都会报错 x is not defined

函数

  • 非严格模式

    function getName() { eval('function gg(){}'); console.log(gg);//未报错 } getName();

  • 严格模式

    "use strict" function getName() { eval('function gg(){}'); console.log(gg);//gg is not defined } getName();

总结

1.对于var、函数声明:

非严格模式下eval里面创建的变量会加载到当前执行上下文,严格模式下eval里面创建的变量在一个新的执行上下文。

2.对let、const

非严格模式和严格模式都一样,只会在新的一个执行上下文。

this强制转型

非严格模式 普通函数调用this指向window,严格模式下指向undefined

image.png

call apply bind 显示调用和硬绑定的this默认值问题

非严格模式下第一个参数this指向为null或undefined,则this指向globalThis,严格模式下指向传递过来的this指向

image.png

装箱问题

非严格模式下会对传递过来的this指向进行装箱(对于number string boolean),严格模式下则不会。

image.png

类与模块

image.png

关于with

  • 非严格模式下

image.png

  • 严格模式下 不能使用with

image.png