红宝书系列之 var let const 的区别

目录

声明风格及最佳实践

var 关键字

1. var 使用

2. var 声明作用域

3. var 声明提升

 let 声明

1. let 作用域

2. 暂时性死区

3. 全局声明(网易前端笔试题)

4. for 循环中的 let 声明

const 声明

1.基本用法

2. for 循环中的 const 声明


声明风格及最佳实践

  • 不使用 var
  • const 优先,let 次之

var 关键字

1. var 使用

var message;           // undefined (未赋初值)

var test = 'hi';       // 字符串类型
test = 100;            // test 重写成数值 100 ,合法,但不推荐

2. var 声明作用域

  • 如果使用 var 定义的变量是在函数内部定义,那么它是一个局部变量,会在函数退出时销毁。
function test() {
    var message = 100;       // 局部变量
}
test();
console.log(message);        // 出错!
  • 但是当省略 var 操作符的时候,就会使得变量成为全局变量
function test() {
    message = 100;           // 全局变量
}
test();
console.log(message);        // 100
  • 定义多个变量直接用逗号隔开
var message = 'hi', age = 10, time = 100;

3. var 声明提升

  • 使用 var 声明的变量会自动提升搭配函数作用域的顶部
function foo() {
    console.log(age);
    var age = 20;
}
foo();            // undefined  不会报错


// 不会报错,因为提升后等价于
function foo() {
    var age;
    console.log(age);
    age = 20;
}
foo();            // undefined  
  • 同时,可以反复多次使用 var 声明同一个变量
function foo() {
    var age = 10;
    var age = 11;
    var age = 20;
    console.log(age);
}

foo();         // 20

 let 声明

1. let 作用域

let 是块级作用域,var 是函数级作用域

// 函数级作用域
if(ture) {
    var name = 'hi';
    console.log(name);  // hi
}
console.log(name);      // hi


// 块级作用域
if(ture) {
    let name = 'hi';
    console.log(name);  // hi
}
console.log(name);      // ReferenceError: name 没有定义
  • 而且,同一个块级作用域不能出现冗余声明,会报错
var name;
var name;   

let age;
let age;   // SyntaxError: 标识符 age 已经声明过了
  • let 和 var 混用也会报错
var name;
let name;   // SyntaxError: 标识符 name 已经声明过了

let age;
let age;   // SyntaxError: 标识符 age 已经声明过了
  • 但是,Js 引擎会记录用于变量声明的标识符以及他们所在的作用域,因此嵌套使用相同的标识符不会出错,因为只要同一个块没有重复声明即可
var name = 'mike';
console.log(name);            // mike
if(true) {
    var name = 'alice';
    console.log(name);       // alice
}

let age = 10;
console.log(age);           // 10
if(true) {
    let age = 25;
    console.log(age);       // 25
}

2. 暂时性死区

产生暂时性死区的原因是因为 let 声明的变量不会在作用域中被提升,在使用未声明的变量到该变量声明之前被称为 “ 暂时性死区 ” 

// name 会被提升
console.log(name);    // undefined 
var name = 'alice';

// age 不会被提升
console.log(age);    // ReferenceError
let age = 10;

3. 全局声明(网易前端笔试题)

  • var 关键字声明的对象会成为 window 对象的属性
  • let 不会
var name = 'mike';
console.log(window.name);     // mike

let age = 10;
console.log(window.age);     // undefined

4. for 循环中的 let 声明

  • let 声明的迭代变量的作用域仅限于 for 循环块的内部,而 var 声明的变量会渗透到循环体外部
for(var i = 0;i < 5;i++){
    // 循环体
}
console.log(i);             // 5

for(let i = 0;i < 5;i++){
    // 循环体
}
console.log(i);             // ReferenceError: i 没有定义
  • var 渗透保存存在的问题(有关宏任务和微任务)
for(var i = 0;i < 5;i++) {
    setTimeout(() => {
        console.log(i);
    },0)
}
// 输出结果为 5,5,5,5,5

原因:在退出循环时,迭代变量保存的时导致循环退出的值:5。在之后执行超时逻辑时,所有的 i  都是同一个变量,因而输出的都是同一个最终值。

  • 而如果使用 let 声明迭代变量,Js 引擎在后台会为每个迭代循环声明一个新的迭代变量,所以每个 setTimeout 引用的都是不同的变量实例,所以每个值就不同。
for(let i = 0;i < 5;i++) {
    setTimeout(() => {
        console.log(i);
    },0)
}
// 输出结果为 1,2,3,4,5

const 声明

1.基本用法

const 的行为与 let 基本相同,唯一一个重要区别是,const 声明变量时一定要初始化,且不能修改 const 声明的变量,会导致运行错误。

const age = 10;
age = 20;         // TypeError: 给常量赋值
  • const 不允许重复声明
  • 作用域也是块级
  • const 声明的限制只适用于它指向的变量的引用。例如:如果 const 变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制,不会报错。
const person = {};
person.name = 'mike';     // ok

2. for 循环中的 const 声明

  • 不能用 const 声明迭代变量,虽然跟 let 一样每次都会声明一个新的迭代变量,但是迭代变量会自增,所以不能用 const。

for(const i = 0;i < 5;i++) {    // TypeError: 给常量赋值
    // 循环体
}
  • 同时,如果仅仅只是声明一个不会被修改的 for 循环变量,那是可以的。
let i = 0;
for(const j = 7;i < 5;i++) {      // ok
    console.log(j);            
}
// 输出结果:7,7,7,7,7

for(const key in {a:1, b:2} ) {
    console.log(key);
}
// a, b

for(const key of [1,2,3,4,5]) {
    console.log(key);
}
//  1,2,3,4,5 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值