作用域
作用域就是一个独立的地盘,让变量不会外泄、裸露进来。也就
是说作用域最大的用途就是隔离变量,不同作用域下同名变量不会有抵触。
全局作用域与部分作用域
最外层函数 和在最外层函数里面定义的变量领有全局作用域
所有 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代码执行结束,变量就会死亡。