金色小芝麻

vuePress-theme-reco 金色小芝麻    2021 - 2023
金色小芝麻 金色小芝麻

Choose mode

  • dark
  • auto
  • light
主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
author-avatar

金色小芝麻

83

文章

27

标签

主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
  • 前端入门

    • 博客搭建过程及相关配置
    • 数组中的16种常用方法
    • JS中的数据类型简析——基本数据类型值
    • JS中的数据类型object基础
    • JS中三种常见的判断
    • 数据类型之间的区别(堆内存Heap VS 栈内存Stack)
    • JS基础练习题及解析
    • 开关灯的小案例
    • JS中数据类型检测方法——typeof
    • 条件判断几个小练习
    • JS循环——for循环
    • 自定义属性实现选项卡小案例
    • 字符串中的12种常用方法
    • DOM操作的简单原理
    • JS实现隔行变色鼠标跟随小案例
    • JS中function的基础知识
    • JS中数组去重的三种方法
    • JS中时间格式化的三种方法
    • JS中URL参数处理的三种方法
    • JS小案例——获取随机验证码
    • DOM操作之——获取DOM标签的9种方式
    • DOM操作之——DOM节点类型及属性
    • DOM操作之——元素的增删改、样式修改、插入内容
    • JS中THIS相关问题梳理
    • JS中的变量提升机制
    • 在全局:私有上下文中:带VAR和不带VAR的区别
    • 作用域和作用域链查找机制
    • JS中堆栈内存的释放问题
    • JS中的闭包机制
    • ES3和ES6定义变量的区别
    • JS中的单例和工厂设计模式
    • JS中的面向对象OOP理论基础
    • 构造函数创建自定义类
    • JS中的原型和原型链
    • Math中常用的9种方法
    • 从一道阿里经典面试题剖析函数三种角色
    • 重写内置call
    • 重写一个内置new
    • 浏览器渲染页面的主体流程
    • 减少DOM的回流和重绘
    • JS中的多种继承方式
    • JS中数据类型检测四种方式的优缺点
    • JS中的正则表达式&&全面梳理
    • 非严格模式 🆚 严格模式的区别
    • 数组方法reduce、filter、flat
    • 获取数组中最大值/最小值的三种基础方法
    • 轮播图——渐隐渐显版
    • 深克隆 VS 浅克隆|深比较 VS 浅比较|回调函数
    • 轮播图——左右切换版
    • 事件及事件绑定、事件对象及事件传播
    • 从在地址栏输入网址到看到页面的过程&&AJAX基础
    • 想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS
    • 面试手写API系列
    • 30张脑图带你从零开始学VUE
    • JS中的盒子模型
    • 初识JS-基础中的基础
    • 前端发展简史
    • JS中的三大类输出方式

非严格模式 🆚 严格模式的区别

vuePress-theme-reco 金色小芝麻    2021 - 2023

非严格模式 🆚 严格模式的区别

金色小芝麻 2020-06-22

严格模式的概念,是从ECMAScript5引入的,通过严格模式,可以在函数内部选择进行较为严格的全局或局部的错误条件检测。

使用严格模式的好处是可以提早知道代码中存在的错误,及时捕获一些可能导致编程错误的 ECMAScript 行为。



支持严格模式的浏览器包括 IE10+、Firefox 4+、Safari 5.1+和 Chrome。

”

# 一、前言——如何使用严格模式

要选择进入严格模式,可以使用严格模式的编译指示(pragma):"use strict"

  • 支持严格模式的引擎会启动这种模式,
  • 而不支持该模式的引擎就当遇到了一个未赋值的字符串字面量,会忽略这个编译指示。

1、如果是在全局作用域中(函数外部)给出"use strict",则整个代码都将使用严格模式。(如果把带有"use strict"的代码放到其他文件的全局中,则该文件中的 JavaScript 代码也将处于严格模式下。)

2、也可以只在函数中打开严格模式,就像下面这样:

function xiaozhima(){ 
  "use strict";
  //其他代码
}
复制代码

如果不想让整篇代码都处在严格模式下,建议只在需要测试的特定函数中开启严格模式。

# 二、严格模式 VS 非严格模式——变量

# 1、创建变量



在严格模式下,什么时候创建变量以及怎么创建变量都是有限制的。

”

  • 在非严格模式下,可以像下面这样创建全局变量:
//未声明变量
a = 1;
//非严格模式:创建全局变量
//严格模式:抛出 ReferenceError message = "Hello world! ";
复制代码

即使 a 前面没有 var 等关键字,即使没有将它定义为某个全局对象的属性,也能将 a 创建为全局变量。

  • 严格模式下,不允许意外创建全局变量。
"use strict"
//未声明变量
a = 1;
//严格模式:抛出 ReferenceError message = "Hello world! ";
复制代码

但在严格模式下,如果给一个没有声明的变量赋值,那代码在执行时就会抛出ReferenceError。

# 2、delete删除变量

  • 非严格模式允许这样操作,但会失败(返回 false)。
var color = "red"; 
delete color;
//删除变量
//非严格模式:静默失败
//返回 false
复制代码
  • 在严格模式下,删除变量也会导致错误。
"use strict"
var color = "red"; 
delete color;
//删除变量
//严格模式:抛出 ReferenceError
复制代码

# 3、变量名

严格模式下对变量名也有限制。

特别地,不能使用 implements、interface、let、package、private、protected、public、static 和 yield 等作为变量名。

这些都是保留字,将来的 ECMAScript 版本中可能会用到它们。在严格模式下,用以上标识符作为变量名会导致语法错误。

# 三、严格模式 VS 非严格模式——对象



在严格模式下操作对象比在非严格模式下更容易导致错误。一般来说,非严格模式下会静默失败的情形,在严格模式下就会抛出错误。因此,在开发中使用严格模式会加大早发现错误的可能性。

”

# 1、在下列情形下操作对象的属性会导致错误:

  • 为只读属性赋值会抛出 TypeError;
  • 对不可配置的(nonconfigurable)的属性使用 delete 操作符会抛出 TypeError;
  • 为不可扩展的(nonextensible)的对象添加属性会抛出 TypeError。

# 2、在使用对象字面量时,属性名必须唯一。例如:

//重名属性
//非严格模式:没有错误,以第二个属性为准
//严格模式:抛出语法错误
var person = {
  name: "Nicholas", 
  name: "Greg"
};
复制代码

这里的对象 person 有两个属性,都叫 name。

  • 非严格模式下:person 对象的 name 属性值是第二个;
  • 严格模式下:而在严格模式下,这样的代码会导致语法错误。

# 四、严格模式 VS 非严格模式——函数

# 1、命名函数的参数必须唯一

以下面这个函数为例:

//重名参数
//非严格模式:没有错误,只能访问第二个参数
//严格模式:抛出语法错误
function sum (num, num){
  //do something
}
复制代码
  • 在非严格模式:这个函数声明不会抛出错误。 通过参数名只能访问第二个参数,要访问第一个参数必须通过 arguments 对象。
  • 严格模式:要求命名函数的参数必须唯一。会抛出错误

# 2、函数体中的arguments

严格模式下,arguments 对象的行为也有所不同。

  • 非严格模式下,修改命名参数的值也会反映到 arguments 对象中,例如:
//修改命名参数的值
//非严格模式:修改会反映到 arguments 中

function showValue(value){ 
  value = "Foo";
  alert(value); //"Foo" 
  alert(arguments[0]); //非严格模式:"Foo"
}
showValue("Hi");

复制代码
  • 严格模式下这两个值是完全独立的。
//修改命名参数的值
//严格模式:修改不会反映到 arguments 中

function showValue(value){ 
  "use strict"
  value = "Foo";
  alert(value); //"Foo" 
  alert(arguments[0]); //严格模式:"Hi"
}
showValue("Hi");

复制代码



以上代码中,函数 showValue()只有一个命名参数 value。调用这个函数时传入了一个参数"Hi", 这个值赋给了 value。而在函数内部,value 被改为"Foo"。

”

  • 在非严格模式下,这个修改也会改变arguments[0]的值,
  • 但在严格模式下,arguments[0]的值仍然是传入的值。

与变量类似,严格模式对函数名也做出了限制,不允许用 implements、interface、let、package、private、protected、public、static 和 yield等作为函数名。

# 3、if 语句中声明函数会导致语法错误

对函数的最后一点限制,就是只能在代码的顶级和在函数内部声明函数。也就是说,在 if 语句中声明函数会导致语法错误:

//在 if 语句中声明函数
//非严格模式:将函数提升到 if 语句外部
//严格模式:抛出语法错误

if (true){
  function doSomething(){
  //...
  }
}
复制代码
  • 在非严格模式下,以上代码能在所有浏览器中运行,
  • 但在严格模式下会导致语法错误。

# 五、严格模式 VS 非严格模式—— eval()

饱受诟病的 eval()函数在严格模式下也得到了提升。最大的变化就是它在包含上下文中不再创建变量或函数。

例如:

//使用 eval()创建变量
//非严格模式:弹出对话框显示 10
//严格模式:调用 alert(x)时会抛出 ReferenceError

function doSomething(){ 
  eval("var x=10"); 
  alert(x);
}

复制代码
  • 非严格模式下,以上代码会在函数 doSomething()中创建一个局部变量 x,然后 alert()还会显示该变量的值。
  • 在严格模式下,在 doSomething()函数中调用 eval()不会创建变量 x,因此调用 alert()会导致抛出 ReferenceError,因为 x 没有定义。

可以在 eval()中声明变量和函数,但这些变量或函数只能在被求值的特殊作用域中有效,随后就将被销毁。因此,以下代码可以运行,没有问题:

"use strict";
var result = eval("var x=10, y=11; x+y");
alert(result); //=> 21
复制代码

这里在 eval()中声明了变量 x 和 y,然后将它们加在一起,返回了它们的和。于是,result 变量的值是 21,即 x 和 y 相加的结果。而在调用 alert()时,尽管 x 和 y 已经不存在了,result 变量的值仍然是有效的。

# 六、严格模式 VS 非严格模式—— eval 与 arguments

  • 严格模式已经明确禁止使用 eval 和 arguments 作为标识符,也不允许读写它们的值。例如:
//把 eval 和 arguments 作为变量引用
//非严格模式:没问题,不出错
//严格模式:抛出语法错误

var eval = 10;
var arguments = "Hello world!";

复制代码
  • 在非严格模式下,可以重写 eval,也可以给 arguments 赋值。但在严格模式下,这样做会导致语法错误。

不能将它们用作标识符,意味着以下几种使用方式都会抛出语法错误:

  • 使用 var 声明;
  • 赋予另一个值;
  • 尝试修改包含的值,如使用++;
  • 用作函数名;
  • 用作命名的函数参数;
  • 在 try-catch 语句中用作例外名。

# 七、严格模式 VS 非严格模式—— this

JavaScript 中一个最大的安全问题,也是最容易让人迷茫的地方,就是在某些情况下如何抑制 this 的值。

  • 在非严格模式下使用函数的 apply()或 call()方法时,null 或 undefined 值会被转换为全局对象。
  • 在严格模式下,函数的 this 值始终是指定的值,无论指定的是什么值。例如:
//访问属性
//非严格模式:访问全局属性
//严格模式:抛出错误,因为 this 的值为 null 

var color = "red";
function displayColor(){ 
  alert(this.color);
}

displayColor.call(null);
复制代码

以上代码向displayColor.call()中传入了null,

如果在是非严格模式下,这意味着函数的this值是全局对象。结果就是弹出对话框显示"red"。

而在严格模式下,这个函数的 this 的值是 null,因此在访问 null 的属性时就会抛出错误。

# 八、严格模式 VS 非严格模式—— 其他

# 1、抛弃了 with 语句。

  • 非严格模式下的 with 语句能够改变解析标识符的路径,
  • 但在严格模式下,with 被简化掉了。因此,在严格模式下使用 with 会导致语法错误。
//with 的语句用法
//非严格模式:允许
//严格模式:抛出语法错误

with(location){ 
  alert(href);
}

复制代码

# 2、去掉了 JavaScript 中的八进制字面量



严格模式也去掉了 JavaScript 中的八进制字面量。以 0 开头的八进制字面量过去经常会导致很多错误。在严格模式下,八进制字面量已经成为无效的语法了。

”

//使用八进制字面量
//非严格模式:值为 8
//严格模式:抛出语法错误

var value = 010;

复制代码

注意⚠️:使用parseInt()解析八进制字面量在严格模式下会被当作以 0 开头的十进制字面量。例如:

//使用 parseInt()解析八进制字面量
//非严格模式:值为 8
//严格模式:值为 10

var value = parseInt("010");
复制代码

文章借鉴于:javascript高级程序设计第三版

# 思维导图

img

作者:金色小芝麻 链接:https://juejin.cn/post/6844904129442086925 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

欢迎来到 金色小芝麻
看板娘