var、let和const

var、let和const

var

不知道你是否和我一样,每次在js中只会用var?用webstorm的小伙伴都知道,每次用WebStorm,都会提示把var改成const或者let。

这其实是ECMAScript6的语法规范,推荐我们用const和let去替代var。ok那么为什么要这样呢?

先来讲讲var:
var声明变量主要有三个特点:
1.变量的声明,会在代码被执行之前被处理。
2.在函数内声明的变量,其可用范围在当前函数作用域内。
3.在函数外声明的变量,其作用范围是全局。

来看下面的代码

//js
(function f() {
  var a =10;
  console.log(a);  // 输出 10
  {
   var a=20;
   console.log(a); // 输出 20
  }
  console.log(a);  // 输出 20
})();
 console.log(a);

运行结果:
在这里插入图片描述
结论:可以看出,在函数内用var声明的变量作用仅在这个函数内,而对函数外部是不作用的。

那对这个代码稍作修改:

//js
var a = 10;
(function f() {
  console.log(a);  
  {
   var a=20;
   console.log(a); 
  }
  console.log(a); 
})();
 console.log(a);

运行结果:
在这里插入图片描述
在这里插入图片描述
第一个变量变成undefined是怎么回事?
会出现undefined,无非就是两种情况,首先,声明了变量没有赋值,在这里显然不是,那么就是变量提升了。
什么是叫变量提升?简单来说就是:用var声明的变量可以在声明之前使用,值为undefined。 如:

//js
console.log(a); // 输出undefined
var a = 2;

那么,为什么会发生这种情况呢?在js中有个特性:层级关系作用域内会优先查找已经在内部声明的变量。
在这里插入图片描述
所以,即使在函数外面对一个变量赋值一旦在函数里面用var声明了变量,函数里面再赋值,那么就会忽略掉函数外部的赋值,从而导致了变量提升。

有一说一,这么解释确实不太严谨。这其实和JS作用域与作用域链有关。可以参考JS作用域与作用域链

let

接着说说let
let的主要特点:
1.不允许在相同作用域内,重复声明同一个变量(代码规范!)
2.不存在变量提升
3.块级作用域
来看下面的代码

//js
{
  let a = 10;
  var b = 1;
}
console.log(b);
console.log(a);

在这里插入图片描述
let与var最大的不同在于其作用域不同,let的声明只在它所在的代码块有效,这就是块级作用域,而var声明的变量类似于其它语言中的全局变量。

在其它很多语言里,比如C语言,Java,在写for循环的时候都会保证计数器i只在循环体内有效,在js里,如果用var去声明 i, 如:

//js
for (var i = 0; i < 10; i++) {
  // 执行相关代码
}
console.log(i);//输出10

循环结束,这个i仍然是有效的,因为是var声明的。而这样写可能会出问题哦
比如:

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

输出的结果是10,并不是我们想要的6。就是因为变量i是var声明的,在全局范围内都有效,所以可以理解为全局只有一个变量i,而数组里的每一个函数指向的都是同一个i,所以最后的输出结果是10.
for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

//js
var a = [];
//将var改成let就可以了
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 输出6

const

const声明的变量只能被赋值一次,然后就不能在被赋值。const语句的作用范围和let语句一样。根据命名规范我们应该用大写字母声明常量。

注意:不能给const重新赋值

//js
function f() {
  const VARIABLE =10;
  console.log(VARIABLE);  // 输出 10
  VARIABLE =20;           // 抛出类型错误
  console.log(VARIABLE); 
}

总结

假如说在写前端页面中,碰到了要给一些button绑定一个事件,用for循环的时候就要当心,如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
</body>
<script>
    var btn = document.getElementsByTagName('button');
    for (var i = 0; i < btn.length; i++) {
        btn[i].onclick = function () {
            window.alert(i)//
        }
    }
</script>
</html>

结果就是,每一个button都会弹出6,而不是我们所愿的。

js中有闭包,可以通过闭包来解决问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
</body>
<script>
   var btn = document.getElementsByTagName('button');
    for (var i = 0; i < btn.length; i++) {
        (function (i) {
            btn[i].onclick = function () {
                window.alert(i)
            }
        })(i)
    }
</script>
</html>

但其实只要将var改成let就好了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
</body>
<script>
    var btn = document.getElementsByTagName('button');
    for (var i = 0; i < btn.length; i++) {
        (function (i) {
            btn[i].onclick = function () {
                window.alert(i)
            }
        })(i)
    }
</script>
</html>

所以,尽可能用const和let去替代var,为了规范!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值