var
和 let
的区别,实际上就是 ES3
定义变量 和 ES6
定义变量的区别javascript
ES3
定义变量的方式:
var
function
ES6
定义变量的方式:
let
const
class
import
ES6
语法相对于ES3
来讲,最大的特色就是让JS
变得更加严谨,告别JS
松散的特色java
LET
和 VAR
的区别let
不存在变量提高,因此变量只能在声明定义后使用var
存在变量提高console.log(n); //=>undefined
var n = 10;
console.log(n); //=>10
console.log(n); //=>Uncaught ReferenceError: Cannot access 'n' before initialization LET不存在变量提高,因此变量只能在声明定义后使用
let n = 10;
console.log(n); //=>10
复制代码
let
是不容许重复声明的
let
重复声明了,会报错var
容许重复声明
var n = 12;
var n = 13;
console.log(n); //=>13
let n = 12;
let n = 13;
console.log(n); //=>Uncaught SyntaxError: Identifier 'n' has already been declared
var n = 12;
let n = 13; //=>Uncaught SyntaxError: Identifier 'n' has already been declared
//=>是否从新声明,并非在代码执行阶段检测的,而是在词法解析阶段检测的(词法解析阶段相似于变量提高,在代码尚未执行以前,就发生了,一旦发现有词法错误 SyntaxError ,当前代码都不会再执行了)
console.log('OK');
var n = 12;
let n = 13; //=>报错 可是OK都没有被执行
复制代码
- 词法解析:词法解析阶段相似于变量提高,在代码尚未执行以前就发生了
- 词法错误
SyntaxError
:在词法解析阶段报错,代码尚未执行就报错,一旦发现有词法错误SyntaxError
,当前代码不会在执行了- 语法错误
ReferenceError
:在代码执行阶段报错,报错前的代码会正常执行
在全局上下文中面试
var n = 10;
console.log(window.n); //=>10
let n = 10;
console.log(window.n); //=>undefined
复制代码
let
能解决基于typeof
检测一个没有被声明过的变量结果是"undefined"
的暂时性死区问题;var
不能浏览器有一个
BUG
(暂时性死区):基于typeof
检测一个没有被声明过的变量,并不会报错,结果是"undefined"
;可是从正确角度来说应该报错才是正常的!浏览器
console.log(typeof n); //=>"undefined"
//=> 若是这个变量在后面会用`LET`声明,则前面再基于`typeof`检测就会报错:不能在声明以前使用
console.log(typeof n); //=>Uncaught ReferenceError: Cannot access 'n' before initialization
let n = 10;
复制代码
let
在遇到除对象/函数等大括号之外的大括号(例如判断和循环)时,会造成新的块级做用域var
没有块级做用域LET
的块级做用域在整个JS
中,目前为止咱们接触的上下文(做用域)只有两种闭包
EC(G)
EC(XX)
此时循环体或者判断体等,都不会单独造成私有的上下文,里面的变量都是所在上下文中的变量。函数
if (1 === 1) {
var n = 10;
console.log(n); //=>10
}
console.log(n); //=>10
for (var i = 0; i < 5; i++) {...}
console.log(i); //=>5
复制代码
可是在
ES6
中,提供了一个新的上下文(做用域)形式:块级做用域ui
- 除对象/函数等大括号之外,若是在其他的大括号中(例如:判断和循环)出现
LET/CONST
等,则会把当前大括号包起来的部分造成一个独立的私有上下文,基于LET/CONST
建立的变量是当前块级做用域域中的私有变量;
if (1 === 1) {
var n = 10; //=>n是全局变量
let m = 20; //=>m是当前大括号包起来的 私有的 块级做用域中的 私有变量
console.log(m); //=>20
}
console.log(n); //=>10
console.log(m); //=>Uncaught ReferenceError: m is not defined
// 相似于造成两个闭包(这里叫作私有的块级做用域)
{
let x = 10,
y = 20;
console.log(x, y);
}
{
let x = 100,
y = 200;
console.log(x, y);
}
for (let i = 0; i < 3; i++) {
console.log(i); //=>0 1 2
}
console.log(i); //=>Uncaught ReferenceError: i is not defined
复制代码
let/const
等i
的值,做为子做用域中的私有变量和咱们基于 VAR
,每一轮循环都建立一个闭包相似spa
LET
和 CONST
的区别CONST
声明的变量,不能从新指向新的值(不能修改指针的指向);let n = 10;
n = 20;
console.log(n); //=>20
const n = 10;
n = 20; //=>Uncaught TypeError: Assignment to constant variable.
console.log(n);
复制代码
用
const
定义的变量值,永远不能被修改了?指针
- 答:不对
- 一、
const
不能更改指的是:这个变量不能在和其余值进行关联了,也就是不能修改const
声明变量的指向- 二、可是能够在不改变指向的状况下,修改堆内存中的信息(这样也是把值更改了)
- 三、因此:
const
声明的变量,不能修改他的指针指向,可是能够改变其储存值的
例以下面这种状况:code
const obj = {
name: '金色小芝麻'
};
obj = [10, 20]; //=>Uncaught TypeError: Assignment to constant variable.
//=> 它不能更改指的是:obj这个变量不能在和其它值进行关联了,也就是不能修改const声明变量的指向
obj.name = '哈哈';
console.log(obj);//=>{name: '哈哈'};
//=>可是能够在不改变指向的状况下,修改堆内存中的信息(这样也是把值更改了),
//=> 因此记住:const声明的变量,不能修改它的指针指向,可是能够改变其存储值的
//=> 因此也就不能说const建立的是一个常量;
复制代码