变量 作用域 作用域链 闭包 this
变量往作用域中储存数据
为什么会有作用域?
因为变量需要运行环境 ; 就是作用域
1:全局作用域在浏览器或者程序刚开始运行时产生
2:全局作用域销毁:在关闭浏览器或关闭程序时
所以:我们声明的全局变量; 都是window 对象下的属性
所以:js 中所有数据都在window下活跃
所以: 全局作用域下最大的对象就是window 每次改变变量值,都是给window 属性重新赋值
window 属性为声明变量 或定义函数名子
变量和函数如何成为window 下属性
因为js 运行要三个阶段
1:语言分析
2: 预编译
2.1: 在全局作用域形成之初,预编译会创建Go对象:也是全局
2.2:先将所有变量提升: 提升到作用域最顶端,赋值为undefined
2.3:2.3在将所有定义的函数,提升到作用域的顶端,并赋值为函数在堆中的指针
注意:变量声明先提升;然后函数定义在提升.所用的变量用值;都是使用最近的一次赋值
----》所以经过预编译后;变量和函数名字就成为了window的属性
3:解析执行
每执行一行代码:都会对window 下的属性进行重新赋值—》也就是数据发生的变化
作用域分类
全局作用域:
window对象下
是最大的作用域
其他作用域都必须在全局作用下
局部作用域:
因为函数体中有声明的变量,函数在执行的时候:该变量运行需要一个环境:所以就产生了局部作用域
当函数执行完毕时,看子作用域中是否有需要使用他声明的变量;如果没有则作用域销毁;变量消失(实际为变量赋值为null),如果用到了,那么就形成了闭包,作用域保存下来
函数执行环境;是在栈内存中,每此执行都会开辟一个空间,执行完毕消失
所以 每个作用域中都有体格最大的对象,局部作用域为Ao对象 全局为Go
每个都有隐藏this ,默认指向该对象。
块级作用域
let 声明的变量{} 时一个代码块; let 只能在自己的{}内部运行,外部不能访问,只看{}不看函数
2:块级作用域页遵循作用域链规则, 小作用域可以使用大作用域的数据
3:for 循环中let 千万注意 不是一个块级域
for(let i = 0; i< 3;i++){
setTimeout(function(){
console.log(i)//0 1 2
},1000)
}
for(var i = 0; i< 3;i++){
// 循环先执行,异步后执行, 循环完毕 i=3
setTimeout(function(){
console.log(i)//3 3 3 i 使用全局变量 i=3
},1000)
}
局部作用域js 是如何执行 编译的
预编译
1: 创建Ao对象 Ao:{}
2: 将函数体中声明的变量提升到作用域顶端, 给Ao添加属性, 赋值为undefined
3:将函数体中函数提升到作用域顶端,给Ao添加属性,属性为函数名;值为定义函数的指针
解析执行
1:每执行一行对Ao中属性重新赋值
2: 如果未经声明
作用域链是什么?
作用域链[scope]
- 作用域是层作用包裹另一 层作用域σ从而形成作用域链,通过scope完成的
- 作用域链导致了变量的使用规则。
- 1:在自己的作用域中找,如果没有就去父域中找,直到找到全局域为止
- 变量查找方式:
- 1;先看声明,再看赋值,赋值使用就近原则
- 注意:xxx=nnnn不是全局的,是变量赋值,不是声明
因为 在预编译阶段:window下没有这个属性: 只有在解析执行的时候;才给window添加属性,并赋值
作用域链的存在:是为了让在小作用域中的变量可以访问大作用域中的变量
var a=1
function b(){
console.log(a)
}
b()
// 如果没有作用域链返回 a is not defined
// 有就返回 1
作用域与作用域之间的关系?
链式关系,大作用域嵌套小作用域,作用域的层层嵌套形成作用域链
什么是作用域链
this 默认就是存在的,每个作用域都有,默认指向当前作用域中的对象【抽象的对象】
1: 函数中作用域是不稳定的
2: 作用域可以赋值给对象
3:对象.函数执行, 可以将tnis 赋值给对象 谁调用指向谁
function(){
this.name =arguments[0]
}
var a =new creatObj; // this 指向 a对象
本文详细探讨了JavaScript中的作用域概念,包括全局作用域、局部作用域和块级作用域的特点,以及作用域链的形成机制。阐述了预编译过程、变量提升和函数提升的细节,解释了this关键字的行为和闭包的原理。
792

被折叠的 条评论
为什么被折叠?



