javascript 严格模式
严格模式是一种特殊的执行模式,它修复了部分语言上的不足,提供更强的错误检查,并增强安全性。
一、如何使用严格模式?
可以在js文件的最开头写入,这样就会在整个js文件中使用严格模式
1 2 3 | “use strict”; function func(){ } |
或者在一个函数的开头写入,这样会在这个函数内使用严格模式
1 2 3 | function func(){ "use strict" ; } |
二、严格模式与普通模式的区别
1、严格模式下,不允许用with
1 2 3 4 5 | ! function (){ with ({x:1}){ console.log(x); //1 } }(); |
在严格模式下使用with会报一个SyntaxError 语法错误
1 2 3 4 5 6 7 | ! function (){ "use strict" ; with ({x:1}){ console.log(x); } }(); //SyntaxError: Strict mode code may not include a with statement |
2、严格模式下,不允许未声明的变量被赋值
在普通模式下:
1 2 3 4 | ! function (){ x=1; console.log(window.x); //1 }(); |
没有使用var声明变量,而是直接给变量赋值,相当于声明了一个全局变量。
在严格模式下:
1 2 3 4 5 6 | ! function (){ "use strict" ; x=1; console.log(window.x); }(); //Uncaught ReferenceError: x is not defined |
没有用var给变量声明而是直接赋值,会报一个ReferenceError错误
3、严格模式下,arguments变为参数的静态副本
在普通模式下:
1 2 3 4 | ! function (a){ arguments[0]=100; console.log(a); //100 }(1); |
定义了函数,并且传参,比如形参a和arguments[0]是有相互绑定关系的,如果修改了arguments[0]为100,那么对应的形参a也会被修改。需要注意的是,如果不给形参传值,比如这里的1不传,那么a的值是undefined,arguments[0]修改为100的话,a的值依然是undefined,不受arguments所影响。
1 2 3 4 | ! function (a){ arguments[0]=100; console.log(a); //undefined }(); |
在严格模式下:
1 2 3 4 5 | ! function (a){ "use strict" ; arguments[0]=100; console.log(a); //1 }(1); |
1 2 3 4 5 | ! function (a){ "use strict" ; arguments[0]=100; console.log(a); //undefined }(); |
arguments已经变成了参数的静态副本,不管参数有没有传值,都不会和arguments相互影响。
但如果传入的参数是对象,修改对象的属性,仍然是会相互影响的。
1 2 3 4 5 | ! function (a){ "use strict" ; arguments[0].x=100; console.log(a.x); //100 }({x:1}); |
4、严格模式下,delect参数、函数名报错
在普通模式下:
1 2 3 | ! function (a){ console.log( delete a); //false }(1); |
删除一个参数会返回false,删除不成功。
在严格模式下:
1 2 3 4 5 | ! function (a){ "use strict" ; delete a; }(1); //Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. |
删除一个参数或函数名会报一个SyntaxError语法错误。
5、严格模式下,delete不可配置的属性报错
在普通模式下:
1 2 3 4 5 6 7 | ! function (a){ var obj={}; Object.defineProperty(obj, "a" ,{ configurable: false }); console.log( delete obj.a); //false }(1); |
删除一个configurable为false的属性,返回false,并且删除失败。
在严格模式下:
1 2 3 4 5 6 7 8 9 | ! function (a){ "use strict" ; var obj={}; Object.defineProperty(obj, "a" ,{ configurable: false }); delete obj.a; }(1); //Uncaught TypeError: Cannot delete property 'a' of #<Object> |
试图删除configurable为false 的属性的话,会报一个TypeError的错误。
6、严格模式下,重名错误
(1)对象字面量重复属性名报错
在普通模式下:
!function() { var obj = {x : 1, x : 2}; console.log(obj.x);//2 }();
在严格模式下:
!function() { 'use strict'; var obj = {x:1,x:2,x:3}; console.log(obj.x);//3 }();
网上说会报SyntaxError错误,本人测试严格模式下木有问题,不知道啥情况。
(2)函数不能有重名的参数:
!function(a,a,b){ "use strict"; return false; }(); //Uncaught SyntaxError: Duplicate parameter name not allowed in this context
正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下,这属于语法错误。
7、严格模式下,禁止八进制字面量
在普通模式下:
!function() { console.log(0123);//83 }();
普通模式下可以识别八进制数
在严格模式下:
!function() { 'use strict'; console.log(0123);//Uncaught SyntaxError: Octal literals are not allowed in strict mode. }();
会报错,SyntaxError错误
8、严格模式下,eval, arguments变为关键字,不能作为变量、函数名
在普通模式下:
!function() { function eval(){} console.log(eval);//function eval(){} }();
在严格模式下:
!function() { 'use strict'; function eval(){}//Uncaught SyntaxError: Unexpected eval or arguments in strict mode }();
9、严格模式下,eval独立作用域
在普通模式下:
!function() { eval('var evalVal = 2;'); console.log(typeof evalVal);//number }();
在严格模式下:
!function() { 'use strict'; eval('var evalVal = 2;'); console.log(typeof evalVal);//undefined }();
在严格模式下,eval中的代码不能创建eval所在作用域下的变量、函数。而是为eval单独创建一个作用域,并在eval返回时丢弃。
正常模式下,Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创设了第三种作用域:eval作用域。
正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。
10、严格模式下,禁止this关键字指向全局对象
在普通模式下:
!function f(){ console.log(this);//window console.log(!this);//false }();
返回false,因为"this"指向全局对象,"!this"就是false
在严格模式下:
!function f(){ "use strict"; console.log(this);//undefined console.log(!this);//true }();
返回true,因为严格模式下,this的值为undefined,所以"!this"为true。
使用构造函数时,如果忘了加new,this不再指向全局对象,而是报错。
function f(){ "use strict"; this.a = 1;//Uncaught TypeError: Cannot set property 'a' of undefined }; f();// 报错,this未定义
11、严格模式下,arguments.caller, arguments.callee被禁用
function f1(){ "use strict"; f1.caller; // 报错 f1.arguments; // 报错 } f1(); //Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.
总结:
不允许用with
所有变量必须声明, 赋值给为声明的变量报错,而不是隐式创建全局变量。
eval中的代码不能创建eval所在作用域下的变量、函数。而是为eval单独创建一个作用域,并在eval返回时丢弃。
函数中得特殊对象arguments是静态副本,而不像非严格模式那样,修改arguments或修改参数变量会相互影响。
删除configurable=false的属性时报错,而不是忽略
禁止八进制字面量,如010 (八进制的8)
eval, arguments变为关键字,不可作为变量名、函数名等
一般函数调用时(不是对象的方法调用,也不使用apply/call/bind等修改this)this指向null,而不是全局对象。
若使用apply/call,当传入null或undefined时,this将指向null或undefined,而不是全局对象。
试图修改不可写属性(writable=false),在不可扩展的对象上添加属性时报TypeError,而不是忽略。
arguments.caller, arguments.callee被禁用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧