先看let和var:

1.

console.log(a); // undefined
var a = 3;
console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 3;
 
在当前代码执行之前,首先会把所有带var关键字的进行声明(带function关键字的也会提前声明并且定义),即所谓的变量提升,let则不存在这种情况。
ps:项目中创建函数,一般都是基于函数表达式来实现,这样防止其提前变量提升,如:
 
let fn = function () {};

2.

var x = 3;
console.log(window.x); // let y = 3;
console.log(window.y); // undefined
 
用var进行全局变量声明的时候,也会给全局对象(浏览器中即window)增加一个对应的属性;但是用let声明的变量不存在这个特点。
仅限于全局变量创建时有这个特点,属于私有的执行上下文中创建的私有变量没有这个特点。
 
function fn() {
var x = 1;
y = 2;
console.log(fn.x); // undefined
console.log(fn.y); // undefined
}
fn();
console.log(window.x); // undefined
console.log(window.y); //

3.

var y = 21;
var y = 24;
console.log(y); //
console.log('OK'); // Uncaught SyntaxError: Identifier 'x' has already been declared
let x = 21;
console.log(x);
let x = 24;
console.log(x);
 
可以看到,用var声明同一个变量多次,前边声明的会被覆盖以最后一次赋值为准,而用let声明同一个变量多次时,并不是在let声明同一变量第二次时报错,浏览器显示在代码第一行就有报错。
因为一段代码在浏览器执行时,大体需要经过编译阶段和代码解析阶段,用var的可以重复声明,是因为在编译阶段中的词法解析阶段可以审核过,执行阶段遇到已经声明过的,不会再重新声明;但是用let的不可以,是因为在词法解析阶段都过不去,所以也就不存在引擎去执行代码的阶段了。

4.

if (1 === 1) {
let x = 3;
console.log(x);
}
console.log(x); // Uncaught ReferenceError: x is not defined
let a = 1;
switch (a) {
case 1:
let x = 2;
break;
}
console.log(x); // Uncaught ReferenceError: x is not defined
try {
let x = 100;
console.log(x); //
console.log(a);
} catch (e) {
let y = 200;
console.log(y); //
}
console.log(x);// Uncaught ReferenceError: x is not defined
try {
let x = 100;
console.log(x); //
console.log(a);
} catch (e) {
let y = 200;
console.log(y); //
}
console.log(y); // Uncaught ReferenceError: y is not defined

从上可以看出,let存在块级作用域,var则没有。

还有一个特殊的,暂时性死区:

console.log(typeof a); //=>undefined
console.log(typeof a); //=>Uncaught ReferenceError: Cannot access 'a' before initialization
let a;

再看let(var)和const

let x = 10;
x = 20;
console.log(x); //
const y = 10;
y = 20; // Uncaught TypeError: Assignment to constant variable.
console.log(y);
const obj = {a: 10};
obj.b = 20;
console.log(obj); // {a: 10, b: 20}
let创建的变量是可以更改指针指向的,也就是可以重新赋值的,但是const声明的变量是不允许改变指针指向的。
ps:之前有人说const创建的是常量,常量即不可更改,但从代码示例可以看出,const声明的基本类型值确实不允许改变,但若声明的是存储对象的地址指针,还是可以操作该对象的,像数字100这种才是真正的常量。

最新文章

  1. 使用 jsoup 对 HTML 文档进行解析和操作
  2. XSS (Cross Site Scripting) Prevention Cheat Sheet(XSS防护检查单)
  3. 微信sdk分享,苹果手机分享到qq好友和qq空间没有反应
  4. c# nullable类型有什么用
  5. 通达信:显示K线图日期
  6. android 实现橡皮擦效果以及保存涂鸦的功能
  7. iOS SEL的简单总结
  8. GRPC在NET上的实践(记录篇)
  9. 获取redis主从复制链SHELL脚本
  10. vcpkg custom triplet
  11. Linux编程 11(shell全局环境变量与局变环境变量)
  12. IDEA配置 gradle
  13. 配置eclipse+SDK+ADT开发环境
  14. Shuffle机制
  15. 20145227鄢曼君《网络对抗》Web安全基础实践
  16. .Net core,EFCore 入门
  17. [SDOI2009]HH的项链(莫队)
  18. txt文件存储问题
  19. python扫描proxy并获取可用代理ip列表
  20. 《转》浅谈EJB

热门文章

  1. 文艺平衡树(区间splay)
  2. CentOS 6.6 下源码编译安装MySQL 5.7.5
  3. CentOS7安装docker以及错误解决
  4. mysql-cluster集群搭建步骤
  5. 两张导图带你走进Spring设计模式与编程思想
  6. Java异常 | Error:java: Compilation failed: internal java compiler error
  7. asp.net core 3.x 身份验证-2启动阶段的配置
  8. ps-如何移动照片里的内容
  9. HDU_5729_rmq+二分
  10. 《C# 爬虫 破境之道》:第二境 爬虫应用 — 第五节:小总结带来的优化与重构