作用域

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

全局作用域与部分作用域

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

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