块级作用域(闭包的原理),let与var的区别

事实上,var的设计可以看做是JavaScript语言设计上的错误,ES6之后改用let,可以将let看成更完美的var
ES5之前因为if和for都没有块级作用域的概念,所以在很多时候,我们都必须借助于function的作用域来解决应用外面变量的问题

1.变量作用域

变量作用域:变量在什么范围内是可用的

{
	var name = 'why';	//代码块中定义的变量
	console.log(name);
}
console.log(name);//也能访问name

2.没有块级作用域引起的问题:if的块级

var fun; 
if(true){
	var name = 'why';
	fun = function(){
		console.log(name);
	}
}
name = 'how';
fun();//此时打印的是how

由于if没有块级作用域,在if中的name不是局部变量,所以在外面更改name的值时,也会随之改变

3.没有块级作用域引起的问题:for的块级

五个按钮,分别点击,控制台分别打印这五个按钮
情况一:ES5中没有使用闭包(错误的方式)

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>

    <script>
        var btns = document.getElementsByTagName('button');
        for (var i = 0; i < btns.length; i++) {
             btns[i].addEventListener('click', function () {
                 console.log('第' + i + '个按钮被点击');
             })
         }
    </script>
</body>

结果:点击任何按钮 i 都是 5
截图
函数里的 i 是引用for里的 i ,本来希望 i 第一次传进来是0,第二次是1…但是for循环遍历完之后 i 变为了5,而点击任何按钮时,此时的 i 已经为5了。

4.if和for都没有块级作用域,而函数有

情况二:ES5中使用闭包
以前为了解决这个问题,利用闭包
为什么闭包能解决问题? 因为函数是一个作用域

<script>
        var btns = document.getElementsByTagName('button');
        for (var i = 0; i < btns.length; i++) {
            (function (i) {
                btns[i].addEventListener('click', function () {
                    console.log('第' + i + '个按钮被点击');
                })
            })(i)
        }
</script>

结果:正确显示截图2
由于函数中的 i 和外面的 i 不同,函数有自己的作用域,当改变外面的i时里面的i不受影响,将函数里的i换成num更好理解,详细过程如下:
详解

以前一直理解为立即调用,当i传进去时立即就调用了。实际是函数有一个作用域,不会根据外面的变量值的改变而改变

使用ES6中的let,就没有上述问题

情况三:ES6中的let
ES6中,加入了let,let它是有if和for的块级作用域的

 <script>
        const btns = document.getElementsByTagName('button');
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click', function () {
                console.log('第' + i + '个按钮被点击');
            })
        }
    </script>

let与var的区别

1.定义变量的作用范围

var 声明的变量 没有局部作用域
let 声明的变量 有局部作用域

{
	var a = 10;
	let b = 20;
}
console.log(a);
console.log(b);//报错10 Uncaught ReferenceError: b is not defined

2.定义变量特点

var 可以定义多次
let 只能定义一次

var a = 1;
var a = 2;

let b = 20;
let b = 30;
console.log(a);
console.log(b);//报错Uncaught SyntaxError: Identifier 'b' has already been declared
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值