javaScript作用域(三个:全局、函数、块级)
全局作用域
- 在全局作用域定义的变量(或函数)在全局范围内都有效
定义的方式
- 在最顶层的区域定义的
- 没有定义的
- 不管在第几层都会直接泄露到最顶层
function a(){
name="藏三"
}
a();
console.log("name:",name) //name:藏三
- 放入window对象里面的属性
函数作用域
- 在函数里面定义的变量
- 变量只能在你的函数作用域里面使用,若出了函数作用域之外则会显示该属性没有定义
使用
function b(){
var name="李四";
let age="18"
console.log(name) // 李四
}
b();
console.log(name);// name is not defined
块级作用域(es6新增)
- 新增定义变量的两个命令let和const
- 这两个命令定义的变量只能在块级作用域里面使用
什么是块级作用域?
- 用大括号括起来的作用域就是块级作用域
//块级0
{
console.log(sex) //undefined
//块级01
{
let name ="张三";
var sex="female"
}
//块级02
{
let age="18"
}
console.log(sex) //female
}
console.log(sex) //female
- 以上的name属性就是块级作用域定义的属性 ,其变量只有在块级01里面有效( age属性只能在块级02里面有效)
- 而sex 用的var命令 其变量在本函数作用域里面都有效如在块级0和块级0外面打印的sex 都为female
块级作用域有什么用
-
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
-
在for循环中若用var 会导致变量泄露
let arr=[];
for (var i=0;i<10;i++){
arr[arr.length]=function () {
console.log(i)
}
}
arr[2]() //10 说明函数里面存入的i(循环变量)泄露为和arr同一级的变量。
//es5解决方案:使用立即执行的匿名函数
for (var i=0;i<10;i++){
( function (i) {
arr[i]=function () {
console.log(i)
}
})(i)
}
arr[2]()// 2 因为此时i被存到了function里面形成了函数作用域所以辞职打印的i为2
//es6 使用let命令
for (let i=0;i<10;i++){
arr[arr.length]=function () {
console.log(i)
}
}
arr[2]()// 2 i全都在块级作用域内 所以刚开始传入的是多少 此时传打印出来的i就为多少