2、let 和 作用域

一、作用域

概念:代码中的某个成员能够起作用的范围

分类:

  • 全局作用域
  • 函数作用域
  • 块级作用域(ES2015加入,{}一对大括号代表一个块级作用域):

二、变量声明

1、var

  • 在块内定义的成员,外部可访问,对于复杂的代码这是非常不利且不安全的

  • 存在变量提升,在声明之前打印的话结果是undefined

if(true) {
    var name = 'Judy'
}

console.log(name) // Judy

2、let

  • 声明的变量只能在代码块内使用,外部不能使用,外部如果使用则会报错

  • 另外let声明的变量不会进行变量提升,因此要先声明,再使用。日常代码写作中也建议如此书写。

if(true) {
    let name = 'Judy'
}

console.log(name) // ReferenceError: name is not defined

3、使用场景:

  • 声明for循环的计数器

当传统的循环出现循环嵌套必须声明不同的变量,但是let关键字可以不需要重新声明,虽然如此,但是仍然建议声明一个新的变量增强可读性。

for(var i = 0; i < 3; i++) {
    for (var i = 0; i < 3; i++){
        console.log(i)
    }
}

// 0 1 2

for(let i = 0; i < 3; i++) {
    for (let i = 0; i < 3; i++){
        console.log(i)
    }
}

// 0 1 2 0 1 2 0 1 2
  • 循环注册事件(闭包的经典使用场景,后续的文章中会有对于循环注册事件的功能优化部分,写好后会将链接补充过来)

在事件的处理过程中需要访问循环的计数器,直接用var声明变量作为计数器得不到我们想要的结果,之前我们通常是借助函数作用域摆脱全局作用域的影响,但是直接用let声明就可以写的很简单,它的内部实现机制是一样的。

// 模拟函数点击事件
// var
const elements = [{}, {}, {}];
const len = elements.length;
for(var i = 0; i < len; i++) {
    elements[i].onclick = function (params) {
        console.log(i);
    }
}
elements[0].onclick(); // 3
elements[1].onclick(); // 3
elements[2].onclick(); // 3

// 写法一: 借助函数作用域避免全局作用域带来的副作用

const elements = [{}, {}, {}];
const len = elements.length;
for(var i = 0; i < len; i++) {
    (function(xc) {
        elements[xc].onclick = function (params) {
            console.log(xc);
        }
    })(i)
}
elements[0].onclick(); // 0
elements[1].onclick(); // 1
elements[2].onclick(); // 2

// 写法二

const elements = [{}, {}, {}];
const len = elements.length;
for(var i = 0; i < len; i++) {
    elements[i].onclick = (function(xc) {
         return function () {
            console.log(xc);
        }
    })(i)
}
elements[0].onclick(); // 0
elements[1].onclick(); // 1
elements[2].onclick(); // 2

// let
const elements = [{}, {}, {}];
const len = elements.length;
for(let i = 0; i < len; i++) {
    elements[i].onclick = function (params) {
        console.log(i);
    }
}
elements[0].onclick(); // 0
elements[1].onclick(); // 1
elements[2].onclick(); // 2

4、说明

for循环有两层嵌套的作用域,外层是for循环本身的作用域,内层是循环体的作用域

for (let i = 0; i < 3; i ++) {
    let i = 'Judy'
    console.log(i)
}
// Judy Judy Judy

可以这样理解

{
    // 外层作用域

    for (let i = 0; i < 3; i ++) {

    // 内层作用域,如果内层找不到i,就会到外层去找,相当于作用域链

        let i = 'Judy'
        console.log(i)
    }
}

备注:如有问题,请给出建议,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值