🔒️ 严格模式究竟限制了什么

阿轩的BUG
文章191
评论56
标签101
站点日志
作者总数:1位
置顶文章:0篇
标签总数:101条
文章总数:196篇
评论总数:56条
微语总数:149条
运行天数:2314天
最近更新:2024-09-30
文章标签
最新评论
Sherlock
2025-08-21
不是应该打包成apk文件吗,怎么突然就运行编译了,下一步呢
老金er
2025-05-25
人生设计非常必要,在信息化发达的今天,周围大部分人依然只能过着人生工程模式生活,长时间生活洗礼后,尽管“人生工程”已经不再适合很多人,他们也无法做出任何改变,人生设计给我们提供了新的思路,值得尝试
赏帮赚
2025-05-25
职场太多的尔虞我诈
三笑
2024-08-16
emlog6.0.1可以升级支持吗?
pony
2024-07-08
这篇文章提供了一种新的人生规划方法——"人生设计",它借鉴了产品设计的理念,鼓励人们以创造性和探索性的方式思考和规划自己的生活。以下是对这篇文章的几个评价维度: 创新性:将产品设计的理念应用于人生规划是一个新颖的视角,为人们提供了一种跳出传统生活轨迹,探索个性化生活路径的方法。 实用性:文章不仅提出了理念,还详细介绍了具体的实施步骤,包括自我评估、制定计划、原型设计和实践选择等,具有很强的操作性。 启发性:通过强调好奇心、不断尝试、重新定义问题等心态,文章鼓励人们打破常规,勇于探索未知,这对于激发个人潜能和创造力具有积极作用。 适应性:"人生设计"理念适用于不同人生阶段和不同背景的人,无论是希望从头开始的人,还是已经取得一定成就但希望探索新方向的人,都可以从中获得启发。 情感共鸣:文章对许多人对传统生活轨迹的不满和对改变的渴望进行了深刻的洞察,能够引起读者的共鸣。 可持续性:人生设计强调的是一个持续迭代和试错的过程,这与现实生活的发展规律相吻合,有助于人们在不断变化的环境中做出适应性调整。 教育意义:作为一种人生规划方法,"人生设计"可以作为教育的一部分,帮助年轻人更早地学会自我探索和规划,为未来的生活和职业发展打下基础。 局限性:尽管"人生设计"提供了一种新的思考框架,但它可能需要个人具备一定的自我认知和反思能力,对于一些缺乏自我探索经验的人来说,可能需要额外的指导和支持。 总体来说,这篇文章提供了一种有价值的人生规划方法,对于那些渴望改变、寻求个性化生活的人来说,是一种有益的参考和指导。
首页实用干货 🌋

一、什么是严格模式

  • 采用具有限制性 JavaScript 变体的一种方式,从而使代码隐式地脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式
  • 严格模式修复了一些导致 JavaScript 引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快
  • 严格模式禁用了在 ECMAScript 的未来版本中可能会定义的一些语法

    不支持严格模式与支持严格模式的浏览器在执行严格模式代码时会采用不同行为。所以在没有对运行环境展开特性测试来验证对于严格模式相关方面支持的情况下,就算采用了严格模式也不一定会取得预期效果

二、如何开启严格模式

  • 一种就是我们经常见的也是以前经常使用的"use strict";(或者'use strict';),它需要在所有语句之前放置

    • 可以在全局开启严格模式

      // 整个脚本都开启严格模式的语法
      "use strict";
      var v = "Hi!  I'm a strict mode script!";
      

      这种情况下不能盲目地合并冲突代码

    • 也可以局部开启严格模式。例如:
      function withStrict(){ 
      "use strict";
      var v = "Hi!  I'm a strict mode script!";
      }
      
  • 另一种就是根据ESM,如果设置了<script type="module"></script>,那么他就会默认开启严格模式

三、严格模式做了什么

全局变量

  • 非严格模式下可以意外创建变量,挂载在全局对象上并继续工作
    image.png
  • 严格模式下无法再意外创建全局变量。严格模式中意外创建全局变量被抛出错误替代
    image.png

    静默失败

  • 在非严格模式下,给只读属性赋值,给不可扩展对象添加新属性,都不会报错
    • 在这里使用Object.definePropertydata2的属性name设置为不可写
    • 可以看到经过我们修改后,name的属性值也没有改变,表明不可写设置成功,但是我们给它进行写的操作也没有任何报错
      image.png
    • 我们再测试一下对不可扩展对象添加属性
    • 这里采用Object.preventExtensions()将它设置为不可扩展
    • 可以看到确实无法添加上say这个属性,但是也没有报错
      image.png
  • 同样的操作给严格模式来一遍,就会发现它是会及时抛出错误的
    • 在给只读属性赋值时,抛出错误,提示了name属性是一个只读属性
      image.png
    • 在给不可扩展属性添加新属性的属性的时候,也抛出错误,提示添加属性失败,该对象为不可拓展对象
      image.png

      函数参数

  • 非严格模式下,可以给函数的形参可以重复,以最后一个重复的为主, 不过如果也可以通过arguments获取每个传入的实参
    image.png
  • 严格模式下,直接抛出错误:此上下文中不允许重复的参数名称
    image.png

    变量使用(with,eval)

  • JS存在有些情况(witheval)会使得代码中名字到变量定义的基本映射只在运行时才产生
  • 严格模式移除了大多数这种情况的发生(禁用了with,限制了eval),所以编译器可以更好的优化严格模式的代码
  • with: 块内的任何名称可以映射到 with 传进来的对象的属性,是在运行时决定的:在代码运行之前是无法得知的
    • 非严格模式下可正常使用
      image.png
    • 严格模式下报错
      image.png
  • eval:可以包含一段代码然后执行
    • 非严格模式下 代码 eval("var x;") 会给上层函数或者全局引入一个新的变量 x . 这意味着,一般情况下,在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义
      image.png
    • 严格模式下, eval 仅仅为被运行的代码创建变量,所以 eval 不会使得名称映射到外部变量或者其他局部变量,也就是说它声明的变量跑不出来了
      image.png

      删除声明变量

  • 非严格模式下,不会报错,也不会成功删除
    image.png
  • 严格模式下,删除声明的变量会报错
    image.png

函数的arguments

  • 非严格模式下,如果对arguments进行修改操作,也会同步到实际形参中, 也就是说arguments[i]和其对应的参数是相互关联的,你改我也跟着改
    image.png

  • 严格模式下, 参数的值不会随着arguments对象的值改变而变化,它会保存函数调用时的原始参数,之后你对arguments进行任何操作都不影响它
    image.png

  • 同时非严格模式下的arguments.callee指向当前正在执行的函数
  • 在严格模式下,arguments.callee 是一个不可删除属性,而且赋值读取时都会抛出异常
    image.png

this

  • 在非严格模式下,对一个普通的函数来说,this总会是一个对象:
    • this它本来就是一个对象;
    • 还是用布尔值,字符串或者数字调用函数时函数里面被封装成对象的this
    • 还是使用undefined或者null调用函数时this代表的全局对象
  • 这一点可以参考一下call,bind,apply实现的时候对this的一个处理
    //如果传入的为null或者undefined则指向全局对象
    if(thisArg === null || thisArg === undefined) {
      thisArg = window
    } else { 
    //用Object对其进行包装
       thisArg = Object(thisArg) 
    }
    
  • 在严格模式下通过this传递给一个函数的值不会被强制转换为一个对象, 你传入什么它就是什么
    image.png

非严格模式下自动转化为对象的过程不仅是一种性能上的损耗,同时在浏览器中暴露出全局对象也会成为安全隐患,因为全局对象提供了访问那些所谓安全的 JavaScript 环境必须限制的功能的途径。

关键字

  • 在严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, staticyield
  • 在严格模式下,你不能再用这些名字作为变量名或者形参名

四、总结

  • 将一些过失错误转成异常:
    • 例如意外的全局变量,修改不可修改的属性,给不可拓展的对象新增属性,函数的参数唯一
  • 简化了变量的使用:
    • 例如禁用了with,禁止eval内变量跑出,禁止删除变量
  • arguments变得安全简单:
    • 例如arguments是调用时实参的拷贝,改变后不影响实参;不再支持 arguments.callee方便优化
  • 更安全的JS
    • 例如通过this传递给一个函数的值不会被强制转换为一个对象
  • 为未来的版本铺平道路
    • 例如一部分字符变成了保留的关键字

      不是很全,只是整理了一些我比较想学习的

上一篇
💫 add(1)(2)(3)你会写了,那么add[1][2][3]呢?
下一篇
👷 忘改 git config user,用公司邮箱提交到私人的github,如何挽救?