作用域和变量

作用域 ? 作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就
是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
全局作用域与局部作用域
最外层函数 和在最外层函数外面定义的变量拥有全局作用域 所有 window 对象的属性拥有全局作用域
JS命名冲突
当变量与函数同名,函数优先,所以既有函数声明和变量声明是,结果指向函数声明
不管是函数同名还是变量重名始终是后者1覆盖前者。
var 要先声明。
函数的作用域

function outFun2() { var inVariable = "内层变量2"; } outFun2(); //要先执行这个函数,否则根本不知道里面是啥 console.log(inVariable) // Uncaught ReferenceError: inVariable is not defined

inVariable 在全局作用域没有声明,所以在全局作用
域下取值会报错
我们需要在全局中声明。就不会报错。
全局作用域与局部作用域
代码中任何的地方都能访问到的对象拥有全局作用域。
1:最外层函数,和在最外层函数外面定义的变量拥有全局作用域。
2:所以未定义直接赋值的变量自动声明拥有全局作用域。
function outFun2() { variable = "未定义直接赋值的变量"; var inVariable2 = "内层变量2"; } outFun2(); //要先执行这个函数,否则根本不知道里面是啥 console.log(variable); //未定义直接赋值的变量 console.log(inVariable2); //inVariable2 is not defined

3:window对象属性拥有全局作用域。
但是全局作用域有缺点,变量自定义没有函数包裹。容易引起命名冲突。
作用域是分层的,内层可以访问外层作用域变量,但是外层不可以访问内层。
块级作用域
块级作用域可以通过let和const声明,在指定快的作用域外无法被访问。
循环中绑定块级作用域的使用
var btns = document.getElementsByTagName('button') for (let i = 0; i < btns.length; i++) { btns[i].onclick = function () { console.log('第' + (i + 1) + '个')

javascript中的作用域链
var a = 100 function fn() { var b = 200 console.log(a) // 这里的a在这里就是一个自由变量 console.log(b) } fn()

作用域链指的是从儿子函数往父函数上面找,直到找到对应的变量,没有找到就是not defined.这一层一层的关系就是作用域链。
变量提升
通常JS引擎会在正式执行之前先进行一次预编译,在这个过程中,首先将变量声明及函数声明提升
至当前作用域的顶端,然后进行接下来的处理。
function hoistVariable() { if (!foo) { var foo = 5; } console.log(foo); // 5 } hoistVariable();

!foo

例子:
var foo = 3; function hoistVariable() { var foo = foo || 5; console.log(foo); // 5 } hoistVariable();

它是怎么解析的呢?
function hoistVariable() { var foo = 3; { var foo = 5; } console.log(foo); // 5 } hoistVariable();

如果当前作用域中声明了多个同名变量,那么根据我们的推断,它们的同一个标识符会被提升至作
用域顶部,其他部分按顺序执行
后面把前面覆盖。
变量的本质
变量就是保存一个数据,接下来要用到它的时候再拿出来。
var name="kobe"; //被分配到栈空间,此时name指向栈空间的"kobe" name="leihao";

kobe被修改为leihao
作用域和变量
文章图片

没有指向堆空间。
var info={name:"kobe"} //第一次赋值是把{name:"kobe"}放到堆空间中 //(它有一个内存地址,info指向内存地址)

这个把它放在堆空间里面。
作用域和变量
文章图片

变量的产生与死亡
1:运行时产生
【作用域和变量】2:js代码执行完毕,变量就会死亡。

    推荐阅读