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