本篇文章给大家带来的内容是关于JavaScript作用域的全面解析(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

作用域决定了变量的生命周期和可见性,变量在作用域范围之外是不可见的。

JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。

全局作用域

在任何函数、块或模块范围之外定义的变量具有全局作用域。可以在程序的任意位置访问全局变量。

当启用模块系统时,创建全局变量会变得困难,但仍然可以做到这一点。可以在 HTML 中定义一个变量,这个变量需要在函数之外声明,这样就可以创建一个全局变量:

let GLOBAL_DATA = { value : 1};

console.log(GLOBAL_DATA);

当没有模块系统时,创建全局变量会容易很多。在任何文件中的函数外声明的变量都是全局变量。

全局变量贯穿于程序的整个生命周期。

另一种创建全局变量的方法是在程序的任意位置使用 window 全局对象:window.GLOBAL_DATA = { value: 1 };

这样 GLOBAL_DATA 变量会随处可见。console.log(GLOBAL_DATA)

不过你也知道这种做法是不好的。

模块作用域

如果不启用模块,在所有函数之外声明的变量是全局变量。在模块中,在函数外部声明的变量都是隐藏的,除非显式导出,否则不可用于其他模块。

导出使函数或对象可用于其他模块。在这个例子中,我从模块文件 sequence.js 中导出了一个函数:// in sequence.js

export { sequence, toList, take };

当前模块可以通过导入来使用其他模块的函数或对象成。import { sequence, toList, toList } from "./sequence";

在某种程度上,我们可以认为模块是一个自动执行的函数,它将 import 的数据作为输入,然后返回 export 的数据。

函数作用域

函数作用域意味着在函数中定义的参数和变量在函数内的任何位置都可见,但是在函数外部不可见。

下面是一个自动执行的函数,被称为IIFE。(function autoexecute() {

let x = 1;

})();

console.log(x);

//Uncaught ReferenceError: x is not defined

IIFE 的意思是立即调用函数表达式,是一个在定义后立即运行的函数。

用 var 声明的变量只有函数作用域。更重要的是,用 var 声明的变量被提升到其作用域的顶部。通过这种方式,可以在声明之前访问它们。看看下面的代码:function doSomething(){

console.log(x);

var x = 1;

}

doSomething(); //undefined

这种事不会发生在 let 中。用 let 声明的变量只能在定义后访问。function doSomething(){

console.log(x);

let x = 1;

}

doSomething();

//Uncaught ReferenceError: x is not defined

用 var声明的变量可以在同一作用域下多次重新声明:function doSomething(){

var x = 1

var x = 2;

console.log(x);

}

doSomething();

用 let 或 const 声明的变量不能在同一作用域内重新声明:function doSomething(){

let x = 1

let x = 2;

}

//Uncaught SyntaxError: Identifier 'x' has already been declared

也许我们可以不必关心这一点,因为 var 已经开始变得过时了。

块作用域

块作用域用花括号定义。它由 { 和 } 分隔。

用 let 和 const 声明的变量可以受到块作用域的约束,只能在定义它们的块中访问。

思考下面这段关于 let 块范围的代码:let x = 1;

{

let x = 2;

}

console.log(x); //1

相反,var 声明不受块作用域的约束:var x = 1;

{

var x = 2;

}

console.log(x); //2

另一个常见问题是在循环中使用类似 setTimeout() 的异步操作。下面的循环代码将显示五次数字 5。(function run(){

for(var i=0; i<5; i++){

setTimeout(function logValue(){

console.log(i); //5

}, 100);

}

})();

带有 let 声明的 for 循环语句在每次循环都会创建一个新的变量并设置到块作用域。下一段循环代码将会显示 0 1 2 3 4 5。(function run(){

for(let i=0; i<5; i++){

setTimeout(function log(){

console.log(i); //0 1 2 3 4

}, 100);

}

})();

词法作用域

词法作用域是内部函数访问定义它的外部作用域的能力。

看一下这段代码:(function autorun(){

let x = 1;

function log(){

console.log(x);

};

function run(fn){

let x = 100;

fn();

}

run(log);//1

})();

log 函数是一个闭包。它从父函数 autorun() 引用 x 变量,而不是 run() 函数中的 x 变量。

闭包函数可以访问创建它的作用域,而不是它自己的作用域。

autorun() 的局部函数作用域是 log() 函数的词法作用域。

作用域链

每个作用域都有一个指向父作用域的链接。当使用变量时,JavaScript 会向下查看作用域链,直到它找到所请求的变量或者到达全局作用域(即作用域链的末尾)。

看下面这个例子:let x0 = 0;

(function autorun1(){

let x1 = 1;

(function autorun2(){

let x2 = 2;

(function autorun3(){

let x3 = 3;

console.log(x0 + " " + x1 + " " + x2 + " " + x3);//0 1 2 3

})();

})();

})();

内部函数 autorun3() 可以访问本地 x3 变量。还可以从外部函数访问变量 x1 和 x2 和全局变量 x0 。

如果找不到变量,它将在严格模式下返回错误。"use strict";

x = 1;

console.log(x)

//Uncaught ReferenceError: x is not defined

非严格模式也被称为“草率模式”,它会草率的创建一个全局变量。x = 1;

console.log(x); //1

总结

在全局作用域中定义的变量可在程序的任何位置使用。

在模块中,在函数外部声明的变量都是隐藏的,除非被显式导出,否则不可用于其他模块。

函数作用域意味着函数中定义的参数和变量在函数的任意位置都可见

用 let 和 const 声明的变量具有块作用域。 var 没有块作用域。

html的代码作用域,JavaScript作用域的全面解析(附代码)相关推荐

  1. Java【冒泡排序】算法, 大白话式图文解析(附代码)

    文章目录 前言 一.排序相关概念 1, 什么是排序 2, 什么是排序的稳定性 3, 七大排序分类 二.冒泡排序 1, 图文解析 2, 代码实现 3, 冒泡排序的优化 三.性能分析 四.七大排序算法总体 ...

  2. yy直播php解析代码,多玩虎牙视频PHP解析调用代码

    虎牙视频站里多数是游戏解说.游戏攻略等视频,对于做游戏视频资源的网站可以从虎牙视频站里调用视频,下面分享虎牙视频PHP解析调用代码,把代码复制一个php文件里,保存后上传到主机空间里调用.vxt天浩博 ...

  3. linux手写涂鸦代码,canvas实现图片涂鸦功能(附代码)

    本篇文章给大家带来的内容是关于canvas实现图片涂鸦功能(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 需求需要对图片进行标注,导出图片. 需要标注N多图片最后同时保存. ...

  4. 【如何给iOS APP加固】之代码混淆及加密 第一章【附代码】

    为了给iOS app加固,我们可以采取以下几种方式: 1.代码混淆 代码混淆是通过修改源代码结构和变量名,使得代码难以被理解和反编译.这可以防止黑客获取应用程序的代码,因为即使他们能够获得源代码,也会 ...

  5. php js函数作用域,javascript 作用域详解

    作用域理解:定义的变量.函数生效的范围.javascript 有全局作用域和函数作用域两种. 注:es6实现let 块级作用域不是js原生的,底层同样是通过var实现的.如果想了解具体细节,请访问ba ...

  6. Cocos Creator下JavaScript实现口红机,附代码

    ​原理 转盘.发射的口红.转盘上的口红添加三个不同的碰撞体: 发射的口红和转盘,转盘上的口红和发射的口红碰撞体能发生碰撞: 发射的口红与转盘碰撞时,在指定(根据转盘旋转的角度)位置添加口红: 发射的口 ...

  7. Cocos Creator下JavaScript模拟射箭效果,附代码

    获取代码 关注微信公众号,发送[射箭]获取代码 效果预览 操作方法 点击屏幕,屏幕出现起始位置标志的圆点,不松开手指,滑动屏幕,控制力度和方向,移动距离越大,弓箭拉伸效果越大,松开以后,箭将沿着结束点 ...

  8. 100行代码搞定实时视频人脸表情识别(附代码)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自|OpenCV学堂 好就没有写点OpenCV4 + Open ...

  9. python之穿越火线游戏代码_Python 大作业之五子棋游戏(附代码)

    Python 大作业--五子棋游戏 姓名:吴欣 学号: 姓名:张雨清 学号: 一 游戏介绍: 我们设计的是五子棋游戏,支持两人一个鼠标对下,黑方用左 键单击,白方用右键单击,谁先下均可,落子无悔,下过 ...

最新文章

  1. 医疗术语自动编码论文总结 (Automated Coding)
  2. InputStreamReader/OutputStreamWriter乱码问题解决
  3. IIS托管管道模式的集成和经典
  4. OSI七层模型加协议
  5. PAT-BASIC-1016-部分A+B
  6. Android中扫描wifi热点
  7. PHP判断远程图片或文件是否存在
  8. 53.Maximum Subarray
  9. java正则表达式中的坑String.matches(regex)、Pattern.matches(regex, str)和Matcher.matches()
  10. 《leetcode : 647. 回文子串 思考分析双指针解法》
  11. 用命令来操作vSphere:十一 PowerCLI命令--虚拟机操作
  12. 中国官员:大数据产业发展需全球携手
  13. 项目3:PHP抽奖程序 ,抽奖规则代码 分时间段
  14. svn删除文件出错的经验总结
  15. zzulioj题库题解(持续更新中.......)
  16. 电磁场数值计算方法matlab,电磁场数值计算法与MATLAB实现
  17. 移动磁盘数据错误循环冗余检查的文件找回方法
  18. 如何解决ping不通问题
  19. java geojson和数据库_GeoJson和TopoJson数据格式的对比
  20. 【JS迷你书】Number类型二进制表示法

热门文章

  1. vue父组件变量传递子组件_Vue2.x中的父组件数据传递至子组件
  2. oracle indices,Oracle PL/SQL INDICES
  3. Leetcode 17 - Letter Combinations of a Phone Number
  4. 机器视觉中的图像采集卡
  5. 【数据结构笔记22】图的遍历例题:拯救007(应用DFS)、六度空间(应用BFS)
  6. C#笔记13 匿名类型、集合初始化器、扩展方法和查询表达式
  7. 淘宝ActiveMQ安装搭建
  8. oracle 闪回技术
  9. Viewport的使用《转》
  10. 如何让jquery-easyui的combobox像select那样不可编辑