JavaScript 作用域

  • JavaScript 作用域
  • JavaScript 局部作用域
  • JavaScript 全局变量
  • JavaScript 变量生命周期
  • 函数参数
  • HTML 中的全局变量
  • ES6中的变量和作用域
    • 通过let和const决定块作用域
    • const创建不可变的变量
  • JavaScript 变量提升
  • JavaScript 初始化不会提升
  • 在头部声明你的变量

你越是认真生活,你的生活就会越美好——弗兰克·劳埃德·莱特
《人生果实》经典语录

JavaScript 作用域

作用域可访问变量的集合。

在 JavaScript 中, 对象和函数同样也是变量。

在 JavaScript 中, 作用域为可访问变量,对象,函数的集合

JavaScript 函数作用域: 作用域在函数内修改。

JavaScript 局部作用域

变量在函数内声明,变量为局部作用域。

局部变量:只能在函数内部访问

// 此处不能调用 carName 变量
function myFunction() {var carName = "Volvo";// 函数内可调用 carName 变量
}

因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量

局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁

JavaScript 全局变量

变量在函数外定义,即为全局变量

全局变量有全局作用域: 网页中所有脚本和函数均可使用。

var carName = " Volvo";// 此处可调用 carName 变量
function myFunction() {// 函数内可调用 carName 变量
}

如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量

以下实例中 carName 在函数内,但是为全局变量。


function myFunction() {carName = "Volvo";// 此处可调用 carName 变量
}
myFunction()
// 此处可调用 carName 变量  前提是myFunction函数执行过
console.log(carName) // Volvo

JavaScript 变量生命周期

JavaScript 变量生命周期在它声明时初始化

局部变量函数执行完毕后销毁

全局变量页面关闭后销毁

函数参数

函数参数只在函数内起作用,是局部变量

HTML 中的全局变量

在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。

function myFunction() {carName = "Volvo";
}
myFunction()//此处可使用 window.carName
console.log(window.carName)

PS:
你的全局变量,或者函数,可以覆盖 window 对象的变量或者函数。
局部变量,包括 window 对象可以覆盖全局变量和函数。

ES6中的变量和作用域

通过let和const决定块作用域

letconst创建的变量只在块作用域中有效。它们只存于包含它们的块中。下面演示的代码,通过let在if语句块中声明一个tmp变量。这个变量仅在if语句中有效。

function func() { if (true) { let tmp = 123; console.log(tmp); // => 123 }
}
func() // 123
console.log(tmp); // => ReferenceError: tmp is not defined

相比之下,var声明的变量作用域的范围是函数范围内的:

function func() {console.log(tmp) // undefined 变量声明提升 还没赋值if (true) {var tmp = 123console.log(tmp) // 123}console.log(tmp) // 123
}
func()
console.log(tmp) // Uncaught ReferenceError: tmp is not defined

块作用域意味着你可在有函数内有变量的阴影。

function func() {let foo = 5;console.log(foo) // 5if(true) {let foo = 10;console.log(foo) // 10}console.log(foo) // 5
}
func()

const创建不可变的变量

let创建的变量是可变的:

let foo = 'abc'
foo = 'def'
console.log(foo) // def

const创建的是变量是一个常量,这个变量是不可变的:

const foo = 'abc'
foo = 'def' // Uncaught TypeError: Assignment to constant variable.

如果一个常量指的是一个对象,那么const并不影响常量本身的值是否是可变的,因为它总是指向那个对象,但是对象本身仍然是可以被改变的。

const obj = {}
obj.prop = 123
console.log(obj.prop) // 123
console.log(obj) // {prop: 123}
obj = {} // Uncaught TypeError: Assignment to constant variable.

如果你想让obj真正成为一个常量,你必须冻结它的值

const obj = Object.freeze({});
obj.prop = 123;
console.log(obj) // {}

也就是说,如果const定义的常量指向的是一个对象。这个时候,它实际上指向的是当前对象的地址。这个地址是在栈里面的,而这个真实的对象是在堆栈里面的。所以,我们使用const定义这个对象后,是可以改变对象的内容的。但是这个地址是不可以改变的。意思也就是不可以给这个对象重新赋值,比如const obj= {}, obj = {},即使是这样,obj好像什么也没有改变,但还是错误的。
然而在普通模式下,并没有报错,而obj.name = 'abc’这是完全可以的。这跟JavaScript存储引用对象的值的方式有密切的关系。

const obj = Object.freeze({})
const newObj = {}
obj.name = 'w3cplus'
newObj.name = 'damo'; console.log(obj) // {}
console.log(newObj) // {name: "damo"}

使用Babel把上面ES6的代码编译成ES5代码:

'use strict';
var obj = Ob

JavaScript 变量提升

  • JavaScript 中,函数及变量的声明都将被提升到函数的最顶部

  • JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明

  • 不存在变量提升

以下两个实例将获得相同的结果:
例子1

x = 5; // 变量 x 设置为 5elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;                     // 在元素中显示 xvar x; // 声明 x

例子2

var x; // 声明 x
x = 5; // 变量 x 设置为 5console.log(x)  // 5

要理解以上实例就需要理解 “hoisting(变量提升)”。

变量提升函数声明变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部

不存在变量提升

new Foo() // Uncaught ReferenceError: Foo is not defined
class Foo {}

JavaScript 初始化不会提升

JavaScript 只有声明的变量会提升,初始化的不会。
实例1

var x = 5; // 初始化 x
var y = 7; // 初始化 yconsole.log(x) // 5
console.log(y) // 7

实例2

var x = 5; // 初始化 xconsole.log(x) // 5
console.log(y) // undefinedvar y = 7; // 初始化 y

实例 2 的 y 输出了 undefined,这是因为变量声明 (var y) 提升了,但是初始化(y = 7) 并不会提升,所以 y 变量是一个未定义的变量。

实例 2 类似以下代码:

var x = 5; // 初始化 x
var y;     // 声明 yconsole.log(x) // 5
console.log(y) // undefinedy = 7;    // 设置 y 为 7

在头部声明你的变量

对于大多数程序员来说并不知道 JavaScript 变量提升

如果程序员不能很好的理解变量提升,他们写的程序就容易出现一些问题。

为了避免这些问题,通常我们在每个作用域开始前声明这些变量,这也是正常的 JavaScript 解析步骤,易于我们理解。


谢谢你阅读到了最后~
期待你关注、收藏、评论、点赞~
让我们一起 变得更强

参考
JavaScript 作用域

推荐阅读
理解js中this的指向(几条规则加例子+call,apply,bind改变this指向)

JavaScript 作用域、变量提升相关推荐

  1. javascript --- js中的作用域 变量提升

    1 求以下函数的输出 1.1 考察点: 变量提升.this.作用域 // 考察点 作用域.this.变量提升 var a = 10 function test() {a = 100console.lo ...

  2. JavaScript:变量提升作用域

    作用域是JavaScript中听上去感觉很简单,其实比较麻烦的一个特性,什么是作用域?我看书籍有一个相对的官方解释:作用域(scope,或译有效范围)就是变量和函数的可访问范围,即作用域控制着变量和函 ...

  3. JavaScript中变量提升是什么?如何实现?

    在进行web前端开发的时候,我们经常会遇到变量提升的情况,那么JS在解析变量的时候是如何做到提升的呢?今天小千就来带大家了解一下. 首先在JS中涉及两种作用域的问题,那么什么是作用域呢? 作用域是代码 ...

  4. JavaScript hoisting(变量提升)学习总结

    定义:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部. JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明. 例如一下两个例子: 例1: ...

  5. JavaScript之变量提升

    1.什么是变量提升(Hoisting)? Javascript中执行上下文 (特别是创建和执行阶段)工作方式的一种认识,在ES6之前是找不到变量提升这个词的 "变量提升"意味着变量 ...

  6. JavaScript的变量提升

    变量提升的表现是,无论在函数中何处位置声明的变量,好像都被提升到了函数的首部,可以在变量声明前访问到而不会报错.简单来说就是通过解析和预编译为代码的函数变量创建上下文环境,使得变量在生命前就可以访问. ...

  7. JavaScript变量提升机制

    JavaScript变量提升机制 Js代码执行前(栈内存)还做了一件事那就是变量提升,Js会在所有var function等关键字的提前声明或者定义.. 看以下的代码: console.log(a); ...

  8. javaScript变量提升以及函数提升

    变量的声明赋值 var a = 1; 上面的代码先声明变量 a,然后在变量 a 与数值 1 之间建立引用关系,称为将数值 1 "赋值"给变量 a.以后,引用变量名 a 就会得到数值 ...

  9. 关于JavaScript的词法作用域及变量提升的个人理解

    关于JavaScript的作用域,最近听到一个名词:"词法作用域":以前没有听说过(读书少),记录一下对此的理解,加深印象. 词法作用域:在JavaScript中,一个函数的作用域 ...

最新文章

  1. CVPR2021|Anchor-free新玩法,一个head统一目标检测,实例分割,姿态估计三种任务...
  2. 搭配飞行员 dinic
  3. 环路的产生及RIP防环机制
  4. TypeScript 之泛型
  5. Oracle中怎么设置一列的列宽,oracle - 所有列的Oracle列宽 - 堆栈内存溢出
  6. python3.x执行post请求时报错“POST data should be bytes or an iterable of bytes...”的解决方法...
  7. java中清空文件夹_java 删除文件夹中的所有内容而不删除文件夹本身的实例
  8. 这家自动驾驶公司,或将引领半封闭物流搬运领域的变革
  9. netbeans java桌面应用程序_java – 使用Netbean的桌面应用程序的状态栏
  10. 常用APP签名存档以及获取签名的几种方式介绍
  11. 备战2022软考网络管理员(1)介绍与开篇
  12. 大数据时代的国际贸易理论新发展
  13. 纯html游戏ios打包,白鹭html5游戏打包成ipa文件工具
  14. Qt模仿360系统托盘
  15. vscode汇编环境配置
  16. XOR Guessing
  17. 离散型特征编码方式:one-hot与哑变量
  18. 收藏的软件测试学习资源
  19. 关于QPS高并发,你了解多少?
  20. 0672-5.16.1-CDSW中Run Experiments异常分析

热门文章

  1. php手机省电,手机耗电量越来越多,这个开关一定要关掉!用电量才不会愈来愈高...
  2. layer 弹出层全屏
  3. 24,、135条综合布线系统专业术语,弱电人必备的知识
  4. 【SQL数据库设计】数据库设计【小型数据库】
  5. 微信小程序运营系列(二)——深入了解商户
  6. Java的四大修饰符
  7. 《PANet:Path Aggregation Network for Instance Segmentation》论文笔记
  8. 下一代数据存储OneStorage闪亮登场,华为打造全场景智能的基石
  9. VR广告飞入寻常百姓家?No,它现在还是海市蜃楼
  10. 「网络IO套路」当时就靠它追到女友