乐趣区

关于javascript:作用域和变量

作用域

​ 作用域就是一个独立的地盘,让变量不会外泄、裸露进来。也就
是说作用域最大的用途就是隔离变量,不同作用域下同名变量不会有抵触。

全局作用域与部分作用域

最外层函数 和在最外层函数里面定义的变量领有全局作用域

所有 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 代码执行结束,变量就会死亡。


退出移动版