块级作用域

块级作用域

在ES6之前,作用域分为全局作用域和函数作用域,全局作用域指最顶部的js作用域,也可以理解为单个js文件内或是script内的最顶层代码。函数作用域也可以称之为局部作用域,其只在函数定义时生成。
在全局和函数作用域中,有许多不合理的地方,例如:

var txt = '外层变量';
function fn() {
  console.log(txt);
  if (false) {
	var txt = '内层变量';
  }
}
fn();//undefined

此打印为undefined,其代码一开始的想法是在fn函数中调用全局作用域下的txt变量,然后再对函数作用域下定义一个txt变量,那为什么后续打印的时候值为undefined呢?其原因在于var声明的变量,其会有变量提升的情况。其执行代码的顺序如下:

var txt = '外层变量';
function fn() {
  var txt
  console.log(txt);	//txt为undefined
  if (false) {
	txt = '内层变量';
  }
}
fn();//undefined

let、const

ES6时引入了let和const声明块级作用域变量的关键字,其相对于var关键字的区别在于

  1. 其定义的变量和常量只在其命令所在的代码块内有效,其let和const声明时会以{}为一个作用域。
{
  let num = 10
  var num2 = 20
}
console.log(num); //num is not defined
console.log(num2);//20

  1. 其不会变量提升,故会导致暂时性死区的情况,不同于var,var会变量提升,其引用变量不会报错,因为定义了num,而let则不会变量提升,在定义前引用变量会使得代码报错。
console.log(num); //undefined
console.log(num2);//ReferenceError: Cannot access 'num2' before initialization
var num = 10
let num2 = 20
  1. 其不能重复声明,规范的代码编写,同一代码下声明多个同名变量会导致后续的引用出错
var num = 10
var num = 20
console.log(num);//20
let num2 = 10
let num2 = 30//Identifier 'num2' has already been declared

其let块级作用域的特性非常适合在for循环中对i的遍历

var a = []
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  }
}
a[5]()	//10

其代码的本意是遍历10次,每次以函数的形式将引用i值的函数存入a数组中,在对下标5的函数执行理应打印的i值为5,其真实打印的值为10,这是因为var的特性,在每个i的值自始自终就只有1个,也就是每个i值的引用指向的都是同一个内存块,其循环完后其值会变成10,故在a数组中每个元素执行打印的都是10。

var a = []
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  }
}
a[5]()	//5

在用let对i进行定义时,其每个循环中,i都是一个独立的值,其每个循环都是一个作用域。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值