浅谈 JavaScript 作用域

2023-10-27

一、什么是作用域

作用是对代码的一个读写操作,域是js能够实现的一个范围。

script标签中var的时候,其实是在最大的window上加了一个属性,如果在script中没有用var声明,而是直接赋值,那就是自动在window上加一个属性,这是系统在找不到声明的时候,自动加的。

console.log(a); //undefined
var a = 1;
console.log(a); //1

 

console.log(a); //报错
a = 1;

 

a = 1;
console.log(window.a);//1

二、解释器

  1. js是一种直译式脚本遇到,遇到script标签后,解释器就开始工作,没有一个长期的前期准备。
  2. 解释器执行js代码至少分两步:预解析和执行代码。
  3. 预解析阶段进行变量声明和函数声明,遇到var变量声明后,不去读取赋值,而是自动给变量赋值为undefined,遇到function函数声明后,不去读/执行函数,而是自动将函数的内容当成一块直接存起来function(){}。functionvar优先级高,遇到同名的变量名和函数名,函数名会将变量名进行覆盖,而变量名不会将函数名覆盖。如果有重名的函数,则后者会将前者覆盖。
  4. 解释代码/执行代码期间才真正改变变量的值,先找到预解析找到的变量和函数,如果有能改变变量值的运算=+*/%++--,则会修改预先的值。

 

alert(a); //function a(){alert(3)}
var a = 1;
alert(a); //1
    
function a(){
    alert(2);
} 
    
alert(a); //1
    
var a = 3;
    
alert(a); //3
    
function a(){
    alert(3);
}

alert(a) //3

a(); //报错

三、全局作用域和局部作用域

  1. 全局作用域:最大的作用域是script标签之间,全局中的最大对象是window,但是script标签是分别解释的,代码是自上而下执行的,script之后还是最大的window,在引入代码的时候,一定要注意引入顺序,因为script标签是分别解释的。
  2. 局部作用域:函数内部也是一个空间(函数构建的空间),可以被看做一个局部作用域。
  3. 如果局部作用域的“预解析空间”(AO-活动对象(Active object))没有找到,那么代码会从上一级的作用域寻找,上级作用域不能在下级作用域寻找。

 

<script type="text/javascript">
    alert(a); //报错
</script>
<script type="text/javascript">
    var a = 1;
</script>

 

<script type="text/javascript">
    var a = 1;
</script>
<script type="text/javascript">
    alert(a); //1
</script>

 

var a = 1;
function fn1(){
    alert(a); //undefined
    var a = 1;
}
fn1();
alert(a); //1

//window  1.Ao分析  {a:undefined,fn1:function(){}}
//
//        2. 代码执行: a = 1
//        
//        
//                    fn1 执行 : 进入到函数内部/函数所生成的局部作用域
//                            1. AO分析 {a:undefined} 
//                            2.执行
//                                  //                              
//                                  
//                                          
//           alert(a)
//                 
//  

四、参数

  1. 形参:相当于隐式声明,在AO上为undefined。
  2. 实参:会在AO分析的时候,给形参一个初始值。

 

var a = 1;
function fn1(a){
    alert(a); //undefined
    a = 2;
}
fn1();
alert(a); //1
// window 1. AO {a:undefined,fn1:function(){}}
//        2. AO {a:1,fn1:funcion(){}}
//              fn1:
//                  1.AO {a:undefined}
//                  2.alert(a); 
//                    AO {a:2}
//              
//              
//              alert(a)
//                      

 

var a = 1;
function fn1(a){
    alert(a); //1
    a = 2;
}
fn1(a);
alert(a); //1
// window 1.{a:un,fn1:function}
//        2.{a:1,fn1:function}
//              fn1: 1.{a:1}
//                   2. alert(1)
//                      {a:2}
//          alert(a)

五、作用域的AO分析

  1. 先看有没有参数,实参会把形参初始化,如果只有形参,那么形参为undefined。
  2. 再看有没有变量声明。
  3. 最后看有没有函数声明,函数会把同名变量覆盖。

 

var age = 99;
function t(age){
    alert(age); 
}
t(5); //5
t(); //undefined
// win 1.AO{age:un,t:fun}
//     2. AO{age:99}
//         t(5): 1. AO{age:5}
//               2. alert(5)
//         t(): 1 AO{age:un}
//              2. alert(un)

 

function t2(greet){
    alert(greet); //function greet(){}
    function greet(){}
    greet = 'hello';
    alert(greet); //hello
}
t2(null);
// t2 1. AO{greet:function(){}}
//    2. alert(greet)
//       AO{greet:"hello"}
//       alert(greet)

 

function a(b){
    alert(b); //function b(){alert(b);}
    function b(){
        alert(b); //function b(){alert(b);}
    }
    b();
}
a(1);
// a 1. AO{b:fun}
//   2. alert(b)
//     b()  1. b AO{}
//          2. alert(b)

 

function a(b){
    alert(b); //1
    b = function(){
        alert(b); //function(){alert(b);}
    }
    b();
}
a(1);
// a 1. AO{b:1}
//   2. alert(b)
//      {b:fun}

六、作用域链

  1. 内层作用域在寻找变量的时候未找到,会沿着作用域上的AO向上寻找,直到全局。
  2. AO成链就是作用域链。

 

//JQ最外层代码
// console.log(window);
// undefined = 1
;(function(window ,undefined) {
    // AO{window:window,undefined:1}
    function(){
        function(){
            function(){
                window.document.getElementById()
            }
        }
    }
})(window);
//写window 是为了 性能  不写undefined 是为了防止被污染
//在低版本的IE和FF浏览器当中 undefined是可以被赋值的

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈 JavaScript 作用域 的相关文章

  • 在 javascript/jquery 中将光标更改为等待

    当调用函数时 如何让光标更改为此加载图标以及如何将其更改回 javascript jquery 中的普通光标 在你的 jQuery 中使用 body css cursor progress 然后又恢复正常 body css cursor d
  • React js Stripe 结账不起作用

    我正在尝试在 React js 应用程序中呈现条带结账默认表单
  • 解析“流”JSON

    我在浏览器中有一个网格 我想通过 JSON 将数据行发送到网格 但浏览器应该在接收到 JSON 时不断解析它 并在解析时将行添加到网格中 换句话说 在接收到整个 JSON 对象后 不应将行全部添加到网格中 应该在接收到行时将其添加到网格中
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • 我想检查 $('#td1').text() === "x" 是否?

    我想检查innerHtml是否有X或O 所以我不能再次添加任何其他东西 但它不起作用 添加检查代码后它就停止了 我在这里尝试做一个简单的XO游戏来更熟悉javascript和jquery 我也不确定是否可以用 jQuery 做到这一点
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 如何防止 Iframe 在与浏览器交互后弄乱浏览器的历史记录?

    因此 就我而言 我使用 Iframe 将 Grafana 附加到我的页面 这为我提供了漂亮且易于使用的图表 可以注意到 每次在图表上进行放大或缩小 使用鼠标单击 交互后 Grafana 的 Iframe 都会在我的 Angular 页面上触
  • Meteor:应用程序无法在 0.9.1.1 版本上运行

    出现类似错误 Error TypeError undefined is not a function evaluating Template create anonymous function iron dynamic template j
  • 在requestAnimationFrame中使用clearRect不显示动画

    我正在尝试在 HTML5 画布上做一个简单的 javascript 动画 现在我的画布是分层的 这样当我收到鼠标事件时 背景层不会改变 但带有头像的顶层会移动 如果我使用 requestAnimationFrame 并且不清除屏幕 我会看到
  • 将div设置为隐藏,延时后可见

    我试图在 X 时间后 也许甚至在随机时间之后 但现在我们只做固定时间 在黑色背景上出现一个黄色方块 function initialSetup if document getElementById yellow null document
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • Babel 7 Jest Core JS“TypeError:wks不是函数”

    将我的项目升级到 Babel 7 后 通过 Jest 运行测试会抛出以下错误 测试在 Babel 6 中运行没有任何问题 但在 Babel 7 中失败并出现以下错误 TypeError wks is not a function at Ob
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • FireFox 中的自动滚动

    我的应用程序是实时聊天 我有一个 Div 来包装消息 每条消息都是一个 div 所以 在几条消息之后 我的 DOM 看起来像这样 div div Message number two div div div div
  • 模块构建失败(来自 ./node_modules/babel-loader/lib/index.js)Vue Js

    我从 GitHub 下载了一个我和我的朋友正在开发的项目 但是当我尝试运行时 npm run serve 我收到这个错误 src main js 中的错误 Module build failed from node modules babe
  • 如何获取给定 DOM 元素的所有定义的 CSS 选择器?

    如何使用 jQuery 获取给定 DOM 元素的所有定义的 CSS 选择器 定义后 我的意思是在应用于任何样式表的所有 CSS 选择器document 在某种程度上 这类似于 FireBug 实现的功能 其中显示所选 DOM 元素的所有应用
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 导致回发到与弹出窗口不同的页面

    我有一个主页和一个详细信息页面 详细信息页面是从主页调用的 JavaScript 弹出窗口 当单击详细信息页面上的 保存 按钮时 我希望主页 刷新 是否有一种方法可以调用主页的回发 同时还可以从详细信息页面维护保存回发 Edit 使用win

随机推荐

  • vue.js -- 样式绑定

    目录 class 字符串形式 对象形式 数组形式 style 字符串形式 对象形式 组件 默认继承父组件class 子组件内嵌式 子组件只有一个最外层节点 子组件有多个最外层节点 使用 attrs传参 class 字符串形式 代码演示
  • python不使用第三方库实现bmp图像处理

    python不使用第三方库实现bmp图像处理 一 背景 二 具体功能实现 2 1 读取bmp图像 2 2 resize功能 2 3 rotate功能 2 4 保存bmp图像 三 完整代码 B站 后续 bilibili CSDN python
  • vue 3.0项目标题icon根据域名动态修改显示不同favicon

    文章目录 前言 一 favicon 二 动态修改 1 域名动态判断 2 参考链接 总结 前言 本人项目是vue3 0 cli项目 是多域名公用的前台项目 所以一个icon不能支持很多域名的项目同时使用 提示 以下是本篇文章正文内容 下面案例
  • Qt 信号槽传递指针

    指针定义 ifndef DEFINE H define DEFINE H include
  • epoll的惊群效应

    1 epoll惊群效应产生的原因 很多朋友都在Linux下使用epoll编写过socket的服务端程序 在多线程环境下可能会遇到epoll的惊群效应 那么什么是惊群效应呢 其产生的原因是什么呢 在多线程或者多进程环境下 有些人为了提高程序的
  • css利用border-radius圆角来设置背景图片为圆角的

    例子
  • 【转】MySQL 的表锁和行锁

    转自 https mp weixin qq com s 8LrPHG7XtsvNJJs58yK 0g 锁是计算机协调多个进程或者纯线程并发访问某一资源的机制 相对于其他数据库而言 MySQL 的锁机制比较简单 其最显著的特点是不同的存储引擎
  • crout分解计算例题_如何计算有理函数的不定积分

    本文中所有不定积分都省略常数项 不同小节的相同字母没有关系 部分分式分解 一般微积分书上都会讲有理函数的部分分式分解 以及如何用这种方法算有理函数的不定积分 方法如下 假设 是给定的有理函数 其中 是多项式 先用多项式除法 令 其中 是多项
  • Django-Model层ORM(五)

    目录 一 数据库配置 setting py全局配置文件中 默认 sqlite3数据库 通过class创建一张表 二 使用mysql数据库 通过class创建数据库表 三 单表操作 添加操作一 实例化book对象调用save 函数 添加操作二
  • 操作系统期末总复习(题库)

    本文说明 本文以习题为主 每题标明对应的书本页面 并作出详细解析 大家可以对照复习 选择题章节并没按书本章节分 计算题和分析题无书本页面位置或详细解析 请大家自行找对应章节进行学习 祝大家都能通过考试 也希望大家点赞支持 操作系统期末总复习
  • Python中的 nonlocal 关键字

    在Python中 nonlocal 关键字用于在嵌套函数中引用外部 但不是全局 作用域的变量 nonlocal 可以使你在嵌套函数内部修改外层 非全局 作用域的变量 为了更好地理解 nonlocal 的作用 我们先看一个没有使用 nonlo
  • ELK6.8版本整合filebeat和kafka收集springboot日志

    一 系统流程图 二 统一springboot的日志格式 方便logstash 已中括号过滤用
  • FFmpeg学习笔记--FFplay播放控制、FFplay基本命令参数、FFplay高级命令参数

    目录 1 FFplay播放控制 2 FFplay命令参数 1 强制显示宽高 用于调整窗口大小 2 设置帧尺寸 仅适用于没有包含帧大小的视频 3 设置像素格式 4 以全屏模式启动 5 禁用音频 视频和字幕 6 设置开始播放的位置 7 设置播放
  • 本地离线安装node-sass

    在使用 vue admin template 作为模板进行项目开发时 其模板中自带的 node sass 版本不一定和我们本地的node 环境一致 且使用 npm i node sass s 重新安装 node sass 也会报各种莫名其妙
  • 【shell】shell之cut用法

    目录 即可即用 命令详细说明 即可即用 提取列的用awk命令更好用 示例1 截取pers文件内冒号分隔的字符串的第3列 命令 命令说明 d 使用冒号 作为域分隔符 f 3 取分隔后的第3列 示例2 取括号内的数值 you age is 19
  • Error:for nested data item, row-key is required.的解决方法

    一 问题描述 遇到这个问题 首先跟着网上的教程更改 去掉package json中的element ui 版本号前面 不行之后我以为是我的版本问题 换了版本之后 报的错误更多了 然后给
  • Pandas使用(二)--筛选出dataframe某列中含有特定元素的行

    Pandas使用 二 筛选出dataframe某列中含有特定元素的行 python复现excel function dataframe筛选数据 方法一 通过条件判断 筛选出tnode列等于31010600000122的行 list to d
  • ubuntu tesseract 调试总结

    1 下载 编译运行Leptonica 下载地址 http code google com p leptonica 版本号 1 69 包名 leptonica 1 69 tar gz依次输入命令 configure make make ins
  • 深入Android系统(十二)Android图形显示系统-2-SurfaceFlinger与图像输出

    createEventConnection 方法返回的是一个IDisplayEventConnection对象mEvents 接着通过IDisplayEventConnection对象的stealReceiveChannel 方法 该方法主
  • 浅谈 JavaScript 作用域

    一 什么是作用域 作用是对代码的一个读写操作 域是js能够实现的一个范围 在script标签中var的时候 其实是在最大的window上加了一个属性 如果在script中没有用var声明 而是直接赋值 那就是自动在window上加一个属性