Web前端入门第 55 问:JavaScript 严格模式与非严格模式区别
JavaScript 默认是非严格模式的,可以通过 "use strict"; 启用严格模式。此声明语句可以放在 JS 文件顶部,也可以放在函数内部。
启用严格模式
1、外部脚本在 JS 文件开头声明,内部脚本在 <script> 标签开头声明,声明后所有 JS 代码启用严格模式:
"use strict";
console.log('Hello World!');
错误写法:
console.log("test");
"use strict"; // 置于代码之后的声明,严格模式不生效!
2、在函数内部声明函数启用严格模式,此时本函数体内部的 JS 代码将启用严格模式:
function strictFunc() {
"use strict"; // 函数级严格模式
let x = 10;
y = 20; // ReferenceError: y is not defined
}
function nonStrictFunc() {
y = 20; // 非严格模式下隐式创建全局变量(不推荐)
}
错误写法:
if (true) {
"use strict"; // 无效!严格模式无法在块级作用域启用
x = 10; // 非严格模式下隐式创建全局变量
}
3、模块化脚本(ES6 Modules)无需显式声明,默认启用严格模式:
// module.js(无需写 "use strict")
export default function() {
x = 10; // ReferenceError: x is not defined
}
4、类(ES6 Class)声明或类方法内部无需显式声明默认启用严格模式:
class MyClass {
constructor() {
x = 10; // ReferenceError: x is not defined
}
}
为何 JS 代码会有两种不同的解析结果?
这就不得不提到历史原因了,JS 之父创造 JavaScript 时,仅用了 10 天时间,这久导致了 JS 在后来使用中发现了一些问题,又由于浏览器的版本迭代必须要兼顾一些旧的代码(不可能浏览器来一个版本更新,直接把所有网站一棒打死),所以就有了 严格模式 的出现,这个模式的用途就是告诉浏览器,我这个网站的代码你按照 严格模式 来解析,无需考虑历史兼容性,可能存在的隐式错误可以先告诉我。
严格模式 vs 非严格模式
主要区别如下:
变量声明
非严格模式:未声明的变量赋值会隐式创建全局变量。
严格模式:未声明的变量赋值会抛出 ReferenceError。
<script>
function test1 () {
y = 10; // 声明为全局变量
}
test1();
console.log(y); // 10
</script>
<script>
function test2 () {
"use strict";
x = 10; // ReferenceError: x is not defined
}
test2();
console.log(x); // test2 报错,此行代码不执行
</script>
静默错误转显式错误
删除不可删除的属性:delete Object.prototype; 在严格模式下报错。
重复参数名:function(a, a) {} 在严格模式下报语法错误。
只读属性赋值:NaN = 1; 在严格模式下报错。
<script>
function test1 (a, a) {
delete Object.prototype;
NaN = 1;
}
test1();
</script>
<script>
"use strict";
function test2 (a, a1) { // 报错 SyntaxError
delete Object.prototype; // 报错 TypeError
NaN = 1; // 报错 TypeError
}
test2();
</script>
this 指向
非严格模式:全局函数中 this 指向全局对象(如 window)。
严格模式:全局函数中 this 为 undefined。
<script>
function test1 () {
console.log(this); // 浏览器中指向 Window 对象,nodejs 中指向 global 对象
}
test1();
</script>
<script>
"use strict";
function test2 () {
console.log(this); // undefined
}
test2();
</script>
eval 和 arguments 限制
eval 变量泄漏:严格模式下 eval 中的变量不会污染外部作用域。
禁用 arguments.callee:防止递归调用导致性能问题。
<script>
function test1 () {
eval('var a = 10');
console.log(arguments.callee); // 指向函数本身
console.log(a); // 10
}
test1();
</script>
<script>
"use strict";
function test2 () {
eval('var a = 10');
console.log(arguments.callee); // 报错 TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
console.log(a); // ReferenceError: a is not defined
}
test2();
</script>
其他限制
八进制表示:禁止 0123,需用 0o123。
with 语句:严格模式下禁用,避免作用域混乱。
保留字限制:如 interface、private 等不能作为变量名。
<script>
function test1 () {
console.log(0123); // 83
with (Math) {
console.log(random()); // 输出随机数
}
var interface = 'str';
console.log(interface); // str
}
test1();
</script>
<script>
"use strict";
function test2 () {
console.log(0123); // SyntaxError: Octal literals are not allowed in strict mode.
with (Math) { // SyntaxError: Strict mode code may not include a with statement
console.log(random());
}
var interface = 'str'; // SyntaxError: Unexpected strict mode reserved word
console.log(interface);
}
test2();
</script>
写在最后
建议始终启用严格模式,强制更安全的编码实践,避免隐式错误,提升代码质量。
Web前端入门第 55 问:JavaScript 严格模式与非严格模式区别的更多相关文章
- web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史
秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...
- Android零基础入门第55节:ImageSwitcher和TextSwitcher使用
原文:Android零基础入门第55节:ImageSwitcher和TextSwitcher使用 上一期我们了解了ViewAnimator组件和ViewSwitcher组件的使用,你都掌握了吗?本期一 ...
- Android零基础入门第77节:Activity任务栈和启动模式
通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...
- web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】
http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...
- web前端(13)—— 了解JavaScript,JavaScript的引入方式
从本篇博文开始,将进入web前端方便最关键最重要的部分——javascript,学到后面你就知道它真的太重要了 什么是JavaScript JavaScript一种直译式的脚本语言,是一种动态类型.弱 ...
- WEB前端工程师整理的原生JavaScript经典百例
一.原生JavaScript实现字符串长度截取 二.原生JavaScript获取域名主机 三.原生JavaScript转义html标签 四.原生JavaScript时间日期格式替换 Date.prot ...
- Web前端基础怎么学? JavaScript、html、css知识架构图
以前开发者只要掌握 HTML.CSS.JavaScript 三驾马车就能胜任一份前端的工作了.而现在除了普通的编码以外,还要考虑如何性能优化,如何跨端.跨平台实现功能,尤其是 AI.5G 技术的来临, ...
- web前端学习之HTML CSS/javascript之一
前端编码之路之坎坷,web前端应该一直是个战场吧,各种浏览器的不兼容,各种小细节的修改,要往一个好的产品经理方向走,实在是难,昨天听了一位十年经验的产品经理讲座,最重要的恐怕就是协调资源的能力,而协调 ...
- JavaScript 正则表达式——预定义类,边界,量词,贪婪模式,非贪婪模式,分组,前瞻
㈠预定义类 示例:匹配一个ab+数字+任意字符的字符串:ab\d. ㈡边界 正则表达式常用的边界匹配字符 ⑴示例1:第一个是没写单词边界 第二个是加上字符边界的效 ...
- Web前端开发规范【HTML/JavaScript/CSS】
前言 这是一份旨在增强团队的开发协作,提高代码质量和打造开发基石的编码风格规范,其中包含了 HTML, JavaScript 和 CSS/SCSS 这几个部分.我们知道,当一个团队开始指定并实行编码规 ...
随机推荐
- P4688 [Ynoi Easy Round 2016] 掉进兔子洞
莫队可以维护种类数 但是无法维护出现次数 考虑离散化以后我们后面腾出了一些空位 那么我们就可以填进那些坑里面 这样做我们就可以用 bitset 直接做与运算 那么 莫队 + bitset 即可
- 试试使用 Vitest 进行测试,确实可以减少bug
vitest的简单介绍 Vitest 是一个基于 Vite 的单元测试框架,专为现代前端项目设计. 它结合了 Vite 的高性能和 Jest 的易用性, 提供了开箱即用的 TypeScript.ESM ...
- 李沐动手学深度学习V2-chapter_convolutional-modern
李沐动手学深度学习V2 文章内容说明 本文主要是自己学习过程中的随手笔记,需要自取 课程参考B站:https://space.bilibili.com/1567748478?spm_id_from=3 ...
- Git工作流介绍
前言 工作流其实不是一个初级主题,背后的本质问题其实是有效的项目流程管理和高效的开发协同约定,不仅是Git或SVN等SCM工具的使用. 集中式工作流 如果你的开发团队成员已经很熟悉Subversion ...
- 从Docker Machine到K8S:容器管理为啥有这么多工具?
2018-11-09 18:01 关注嘉为科技,获取运维新知 目录 1.有了Docker,为啥还需要额外容器管理工具 2.Docker三剑客 Docker Machine Docker Compo ...
- java的数据类型之基本类型
强类型语言 要求变量的使用要严格符合规定,所有变量都必须先定义后使用.如果没有按照指定要求使用变量,则该变量将报错.java就是强类型语言. java的两大数据类型 1.基本类型 2.引用类型 其中基 ...
- 【JDBC第4章】操作BLOB类型字段
第4章:操作BLOB类型字段 4.1 MySQL BLOB类型 MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据. 插入BLOB类型的数据必须使用Pre ...
- 必须添加对程序集"System.Core"的引用
异常波浪线 解决办法 <system.web> <compilation> <assemblies> <add assembly="System.C ...
- word突然无法转换latex公式的解决尝试
正常情况下我在word插入复制的latex公式步骤如下(以\(\mu\neq 10\)为例): 把\(\mu\neq 10\)粘贴到word文档中,选中\(\mu\neq 10\)并同时按下alt和等 ...
- xe下ro流导致的错误
server端ro7.0的版本,client用的Xe10.3下Ro9.0.导致clientdataset数据记录有几十条就会出现内存泄漏现象.根源在下面: Remobjects9.0与XE10.3自带 ...