凭什么只有我不能触摸她的心?JavaScript的作用域?作用域链?预编译?

news2024/11/23 22:34:37

前言

凭什么后来者居上?凭什么她的心只有我不能触摸?(o(╥﹏╥)o)

让我从JavaScript中的作用域、作用域链和预编译开始聊聊,相信你一定能从中有收获的

什么是的作用域?

简单来说就是能被访问的区域,在JavaScript中分为三种作用域,全局域、函数域和块级作用域,这里就不做细说了,可参考我的上一篇文章《浅谈JavaScript中的作用域》

什么是作用域链?

简单来时说就是一个一个作用域连起来,成了一条链子,有点抽象,看看图吧

image.png
这个关系可以一直套娃的,小的可以访问大的,大得不能访问小的,就好比在你心里深处的她,她已经参透你,拿捏你,可你却完全看不懂她

什么?你说我怎么在最里面?我劝你最好别问,怕你难过

来点专业点的解释

作用域链是一个由多个变量对象组成的链条,在引擎进行预编译的时候,会把当前作用域内的函数声明和变量声明等信息收集起来,形成一个变量对象。之后再将这个变量对象与父作用域的变量对象链接起来,不断重复,最终就构成了作用域链

什么是预编译?

简单来说就是,代码在执行前需要进行编译操作,用于确定代码之间的各种关联

情人节送礼物不得先看看你和她的关系?

别看了,你不在她心里,你收不到礼物的!!!

什么?你说为什么你送给她的礼物在我手里?那我只能说你不懂作用域链

不懂没事,继续往下,我给你捋捋

关系

通过一个一个作用域的关联,形成作用域链

为什么作用域能够清晰划分呢?他里面的变量凭什么我就不能访问?

预编译就是为了帮助作用域链去进行变量查找

现在知道为什么我收到了你的礼物了吧,情人节我和她要,她可不就和你要了?

预编译过程(重点)

每个函数都有一个内部属性[[scope]]用于存储函数中的有效标识符

在编译时

  1. 变量声明,声明提升 如:var a = 10 中声明提升 var a 后面才是a=10 而不是整体提升var a = 10
  2. 函数声明,整体提升

在全局和函数体内流程有所不同

  • 全局

    1. 创建GO对象
    2. 找变量声明,将变量名作为GO的属性名,值为undefined
    3. 在全局找函数声明,将函数名作为GO的属性名,值为该函数体
  • 函数体内

    1. 创建一个AO对象
    2. 找形参和变量声明,将形参和变量名作为AO的属性名,值为undefined
    3. 形参和实参统一
    4. 在函数体内找函数声明,将函数名作为AO的属性名,值为该函数体

这段代码如何编译的?

function test() {

}

函数调用,在引擎中创建这个函数的执行上下文对象,称之为AO action object,记录有效标识符,执行完之后会被回收掉

image.png

那么这段代码会如何编译呢?

function a() {
    function b() {
        b = 22;
    }
    var a = 111;
    b();
    console.log(a);
}
var glob = 100;
a();

我们来分析一下

首先会创建GO,GO里面存放着变量、函数,并且变量的值为undefined

image.png

创建完毕后,开始调用,调用a()后,创建AO对象,将形参和变量名作为AO的属性名,值为undefined,形参和实参统一,在函数体内找函数声明,将函数名作为AO的属性名,值为该函数体

image.png

其实这个就是该段就是函数a的作用域链

image.png

当执行a时又发现了b函数,于是就又给b创建作用域了,b的作用域首先肯定是指向a的作用域的,因为是a的执行带来了b的创建

image.png

后来执行b了,于是给b创建内部的作用域

image.png

接下来分析这段代码会输出什么?

function fn(a){
    console.log(a);
    var a = 123;
    console.log(a);
    function a(){}
    console.log(a);
    var b = function(){}
    console.log(b);
    function c(){}
    var c = a
    console.log(c);
}
fn(1);

第一次创建GO对象

GO{
    fn:function
}

执行后创建a的oa对象

AO{
    a:undefined 1 function
    b:undefined
    c:undefined function 123
}

所以执行后结果问为function 123 123 function 123

总结

相信看完本章你一定能明白()

凭什么只有你不能触摸她的心?

为什么你送给她的礼物在我手里?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1827045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ROS-SLAM雷达

使用前准备工作 1、新建工作空间、编译功能包 以建立名字为rplidar_ws为例,终端输入 mkdir rplidar_ws cd rplidar_ws mkdir src cd src catkin_init_workspace rplidar_ros功能包:git下载。 https://github.com/Slamtec/rplidar_ros/ 然后把解压的…

vue(v-if,v-else-if-else-show)

基本应用 例子 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTE-8"> <meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-w…

斯坦福ALOHA机器人团队最新论文-HumanPlus: 从人类学习的人形机器人动作模仿和自主操作

斯坦福ALOHA机器人团队最新论文-HumanPlus&#xff0c;继续推进了机器人技术的前沿进展&#xff0c;我进行了部分翻译和解读&#xff1a; HumanPlus人形机器人系统技术解读 1 简介 本教程将介绍一个名为HumanPlus的全栈式人形机器人系统。该系统能够让机器人从人类数据中学习…

面向事件编程之观察者模式

前言 村里的老人常说&#xff1a;真男人就该懂得遵守“三不原则”——不主动、不拒绝、不负责。 一个复杂的软件系统&#xff0c;其中必然会存在各种各样的“对象”&#xff0c;如果在设计之初没有注意控制好耦合度&#xff0c;导致各个对象甚至是函数之间高度耦合&#xff0…

如何用 Google Chrome 浏览器浏览经过 XSLT 渲染的XML 文件

对于经过 XSLT 渲染的XML 文件&#xff0c;本来&#xff0c;可以直接用 IE (Internet Explorer) 打开&#xff0c;就能看到渲染之后的样子&#xff0c;很方便。但是后来&#xff0c;微软把 IE 换成了 Microsoft Edge&#xff0c;按理说这是比 IE 更先进的浏览器&#xff0c;可是…

centos7系统使用docker-compose安装部署jenkins

CentOS7系统使用docker-compose安装部署jenkins&#xff0c;并实现前后端自动构建 记录一次在给公司部署jenkins的真实经历&#xff0c;总结了相关经验 1.准备环境 1.java 由于最新的jenkins需要jdk11以上才能支持&#xff0c;而系统里的jdk是1.8的&#xff0c;因此等jenkins…

qmt交易框架2.0版本----支持实时高频交易

经过了2个星期的开发&#xff0c;终于迎来了qm交易框架2.0&#xff0c;超过了3000行源代码&#xff0c;使用类开发&#xff0c;使用方便。 我们看看利用框架写一个简单的实时高频交易策略&#xff0c;很简单 源代码 from qmt_trader.qmt_trader import qmt_traderfrom qmt_tr…

工业 web4.0 的 UI 卓越非凡

工业 web4.0 的 UI 卓越非凡

求导,积分

求导公式&#xff1a; 复合函数求导法则&#xff1a;两个函数导函数的乘积. 例如&#xff1a;f(x)2x1,f(x)2,g(x)x^24x4,g(x)2x4 那么复合函数&#xff1a; g(f(x))(2x1)^24(2x1)4 把&#xff08;2x1&#xff09;看做整体,则g2(2x1)4 然后再求&#xff08;2x1&#xff09;的导函…

代码随想录算法训练营刷题复习1 :动态规划背包问题 01背包+完全背包

动态规划刷题复习 一、01背包 416. 分割等和子集1049. 最后一块石头的重量 II494. 目标和474. 一和零 416. 分割等和子集 class Solution { public:bool canPartition(vector<int>& nums) {int sum0;for(int i0;i<nums.size();i) {sumnums[i];}if(sum%2!0)retu…

Tuple 元组

文章目录 一、什么是元组 &#xff1f;二、元组的具体操作2.1 创建元组2.1.1 tuple() 创建元组函数和 list() 创建列表函数总结 2.2 元组的元素访问操作2.3 元组的元素计数操作2.4 zip 对象 一、什么是元组 &#xff1f; 列表属于可变序列,可以任意修改列表中的元素。 元组的…

JUC并发编程-第二天:线程池相关

线程池相关 线程池内置线程池的使用线程池的关闭excute方法和submit方法的区别 线程池 线程池就是一个可以复用线程的技术 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,Thread…

HTML静态网页成品作业(HTML+CSS)——游戏永劫无间网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。 二、作品演示 三、代…

初见 Rollup 的十大常见问题

文章目录 初见 Rollup 的十大常见问题1. 超神奇的 Rollup 英文解释&#xff01;2. 为什么 ESM 要比 CommonJS 要好呢&#xff1f;3. 什么是 tree-shaking ?4. 如何使用 Rollup 处理 CommonJS&#xff1f;5. 为什么 node-resolve 不是一个内置功能&#xff1f;6. 为什么在进行代…

网络协议,OSI,简单通信,IP和mac地址

认识协议 1.讲故事 2004年&#xff0c;小明因为给他爹打电话&#xff08;座机&#xff09;费用太贵&#xff0c;所以约定一种信号&#xff0c;响一次是报平安&#xff0c;响两次是要钱&#xff0c;响三次才需要接通。 2.概念 协议&#xff1a;是一种约定&#xff0c;这种约…

如何实现电脑监视员工的电脑屏幕?六个方法偷偷分享给你

实现电脑监视员工的电脑屏幕&#xff0c;通常需要借助专业的监控软件或系统&#xff0c;这些工具旨在帮助企业管理者监督员工的工作状态&#xff0c;确保工作效率&#xff0c;同时保护公司资产和数据安全。以下是几种常见的实现方式。 1. 使用专业的远程监控软件 安企神软件&a…

kaggle竞赛实战10——特征优化

特征优化思路&#xff1a; 在完成常规流程后&#xff0c;如果不知道怎么办&#xff0c;可以针对文本or时间序列特征进行进一步处理 首先&#xff0c;我们注意到&#xff0c;每一笔信用卡的交易记录都有交易时间&#xff0c;而对于时间字段和文本字段&#xff0c;普通的批量创…

解决用Three.js实现嘴型和语音同步时只能播放部分部位的问题 Three.js同时渲染播放多个组件变形动画的方法

前言 参考这篇文章ThreeJSChatGPT 实现前端3D数字人AI互动&#xff0c;前面搭后端、训练模型组内小伙伴都没有什么问题&#xff0c;到前端的时候&#xff0c;脸部就出问题了。看我是怎么解决的。 好文章啊&#xff0c;可惜百度前几个都找不到&#xff0c;o(╥﹏╥)o 问题情况 …

【C++】环境搭建及基本工作流程

C 当你需要写性能良好的代码时&#xff0c;C仍是不二选择 如果你想访问硬件、如果你想对硬件进行控制&#xff0c;C仍是首选。 所有的游戏引擎都是用C编写的&#xff0c;因为C可以直接控制硬件。 原理&#xff1a; C代码-->编译器编译comple-->目标平台的机器码-->放…

[算法刷题—二分法]寻找插入位置

题目展示: 本道题本身并不是很难,主要是学习和分析二分查找插入位置的方法。 首先大体上分为两种情况: 一.target在待查找的数组之中,返回对应值的下标索引。 二.target不在待查找的数组之中&#xff0c;需要返回target插入位置的索引(原数组有序) 第一种情况不难&#xff…