JS关键词let、const、var

更新时间: 2022-08-11 10:31:49
点击量: 1014
标签: 前端js

简介:js常量变量声明方式的区别

文章均为个人原创, 搬运请附上原文地址感谢, 原文来自MasterYi博客

关键词

  • 基本的关键词指针, 学过C语言的应该知道,我们的变量其实只是对应的内存单元地址的一个指针, 指针也就是内存地址

var

  • 存在变量提升 (js 执行前var的变量会自动放置前方执行声明, 默认undefined)
  • 不存在块级作用域 (除了闭包函数体内)
  • 会给全局添加属性:浏览器的全局对象是window,Node的全局对象是global
  • 可以不设置初始值
  • 能改变指针方向
  • 允许重复声明, 会覆盖之前的声明
  • 因为无块级作用域某些场景会泄漏为全局变量
复制/*---- 变量提升 ----*/
console.log(a); // 变量提升不会报错, 打印undefined
var a = 1;
console.log(a, window.a); // 打印 1 1  var声明变量会给全局添加属性


/*---- 块级作用域 ----*/
if(true){
    var b = 1;
}
console.log(b); // 无块级作用域 打印 1


function testb(){
    var c = 'a';
}
let testb_ = () => {
    var c = 1;
}
testb(); 
console.log(c);  // 局部作用域 无论闭包还是箭头 都无法访问到 直接报致命错误


/*---- 无类型声明 ----*/
function testd(){
    d = 1;
}
testd();
console.log(d, window.d);// 打印 1 1  这种不加声明类型的也会全局访问, 即便在函数体内声明也是如此


/*---- 初始值 ----*/
var e; // 不会异常, 默认值为undefined


/*---- 重复声明 ----*/
var f = 1;
var f = 2; // 不会异常,覆盖前面声明的值


/*---- 改变指针方向 ----*/
var g = 1; 
g = {}; // 允许改变指针方向
  • 使用var会泄漏为全局变量的场景
复制    for(var a = 1; a < 10 ; a++){
    }
    console.log(a); // 打印10 因为原有的var无块级作用域会泄漏为全局变量, 改为let即可
    
    if(true){
        var b = 1;
    }
    console.log(b); // 打印1 var无块级作用域会泄漏为全局变量
    
    var arr = [1, 2, 3]
    while (arr.length){
        var c = arr.pop();
    }
    console.log(c); // 打印 1  var无块级作用域会泄漏为全局变量
    
    switch (1){
        case 1:
            var d = 1;
    }
    console.log(d); // 打印 1  var无块级作用域会泄漏为全局变量

let

  • 不存在变量提升, 未执行声明前不允许使用 直接报致命错误
  • 块级作用域
  • 可以不设置初始值
  • 能改变指针方向
  • 同一 作用域 下不允许重复声明
复制/*---- 变量提升 ----*/
// console.log(a); // 不存在变量提升,抛异常, 未执行声明前不允许使用, 也被称为暂时性死区
let a = 1;
console.log(a, window.a); // 打印 1 undefined  let声明变量不会给全局添加属性


/*---- 块级作用域 ----*/
let b = () => {
    console.log(`b`)
}

if(1){
    // console.log(b); // 此处如果使用b, 反而会抛一个异常, 此处知识就设计到了JS执行上下文和变量提升的问题了
    let b = 1; // 忽略上方那一行, 这里正常
    console.log(b); // 打印1 
}
console.log(b); // 打印() =>{ console.log(`b`) }


/*---- 初始值 ----*/
let c; // 不会异常, 默认值为undefined


/*---- 重复声明 ----*/
let d = 1;
// let d = 2; // 同一作用域下, 会抛异常
if(true){
    let d = 2; // 不会异常, 不在同一作用域了
}

/*---- 改变指针方向 ----*/
let e = 1;
e = {}; // 允许改变指针方向

const

  • 不存在变量提升, 未执行声明前不允许使用 直接报致命错误
  • 块级作用域
  • 声明必须设置初始值
  • 不能改变指针方向
  • 同一作用域下不允许重复声明
复制/*---- 变量提升 ----*/
console.log(a); // 不存在变量提升,抛异常
const a = 1;
console.log(a, window.a); // 打印 1 undefined  const声明变量不会给全局添加属性


/*---- 块级作用域 ----*/
if(true){
    const b = 1;
}
console.log(b); // 块级作用域 抛异常


/*---- 初始值 ----*/
const c; // 必须有初始值, 抛异常


/*---- 重复声明 ----*/
const d = 1;
// const d = 2; // 同一作用域下, 会抛异常
if(true){
    const d = 2; // 不会异常, 不在同一作用域了
}

/*---- 改变指针方向 ----*/
const e = {}; // 常量 C里面也称为常指针
// e = 1; // 不允许改变指针方向, 会直接抛异常
e['test'] = 1; // 正常, 因为指针方向没有改变,只是改变对象内部的属性值 

const f = [];
f.push(1); // 与上同理