JavaScript作用域经典例子详解 var与let 补充const的使用

  • ES5之前因为if和for都没有块级作用域的概念,只有function有作用域,所以很多时候都必须借助于function的作用域来解决应用外面变量的问题
  • ES6中加入了let,let有if和for的块级作用域

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

大括号是一个代码块

{
    var name = 'hammer';
    console.log(name);
}
console.log(name);
  • 代码块内定义的变量在代码块外也能使用
  • 代码块对于var定义的变量来说不是作用域的限制,即没有块级作用域

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

var func;
if (true) {
    var name = 'hammer';

    func = function () {
        console.log(name);
    }
}

name = 'sister'

func();
  • func()调用打印的是sister
  • func()调用是为了打印if块内定义的那个name也就是hammer,但是在func()调用之前name被改掉了

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

经典例子:五个按钮,点击哪个按钮就打印“按钮几被点击了”

body标签内包含五个button

<button>按钮0</button>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>

下面是三种不同的js写法

第一种写法:ES5中没有使用闭包(错误的)
var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
     btns[i].addEventListener('click', function () {
         console.log('第' + i + '个按钮被点击');
     })
 }
  • 这样写不管点击哪个按钮,显示的都是第5个按钮被点击
  • addEventListener里面的函数被执行的时候,i已经被改掉了,js异步执行
第二种写法:ES5中使用闭包
var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
    (function (num) {
        btns[i].addEventListener('click', function () {
            console.log('第' + num + '个按钮被点击');
        })
    })(i)
}
  • 闭包可以解决问题,因为函数是一个作用域
  • 但是闭包的写法不利于代码阅读,看上去很复杂
  • (function(){/* code */})();这是立即调用函数的一种写法,里面的函数表达式会被立即调用
  • 关于函数作用域
var name = 'hammer';
function abc(name) {
    console.log(name);
}

name = 'sister';
abc('aaa');
// 打印的是aaa,传入的aaa是输入abc函数的作用域的name,函数优先调用属于自己name,外面name更改不会影响函数里面,这也是形参存在的意义
// 所以上面的闭包,内部的函数有自己num,传入i之后,外面i被改掉不会对里面有影响,相当于那里有五个函数
第三种写法:ES6中的let
const btns = document.getElementsByTagName('button')
for (let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮被点击');
    })
}
  • 最好的实现方式

总而言之,ES5中的var是没有块级作用域的(if/for),ES6中的let是有块级作用域的(if/for)


补充:const的使用

建议在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let

注意一:一旦给const修饰的标识符被赋值之后不能修改

错误示范:

const name = 'hammer';
name = 'sister';

注意二:使用const定义标识符必须进行赋值

错误示范:

const name;

注意三:常量的含义是指向的对象不能修改,但是可以改变对象内部的属性

const obj = {
    name: 'hammer',
    age: 20,
    height: 1.81
}

console.log(obj);

obj.name = 'sister';
obj.age = 40;
obj.height = 2.10;

console.log(obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值