JS与ES6的声明命令(1)- var let const

JavaScript是ECMAScript的实现,ECMAScript是JavaScript的标准。
在声明变量的声明命令上,ES5只有var命令、function命令2种,ES6有let命令、const命令、import命令、class命令4种,因此ES6有6种声明命令。
声明命令
一 变量与宿主环境的关系

  • 宿主环境
    宿主环境是指不仅提供基本的ECMAScript实现,同时也会提供该语言的扩展,以便语言与环境之间交互

  • 常见的宿主环境

    • Web浏览器环境
    • Node环境
    • WebWorker环境
  • 顶层对象

    • 浏览器环境:window对象
    • Node环境:global对象
    • ES5中声明的全局对象等价于顶层对象
    • ES6中声明的全局对象不属于顶层对象的属性
    • 通用方法,会使用 this
var a = 1;
console.log('window.a: ', window.a);//1

let b = 1; 
console.log('b: ', window.b);//undefined

存在的问题
ES5的顶层对象在各种环境的实现不统一
各个环境对比
二 var命令

  • 定义变量
    var(操作符)+ 变量名(标识符) ;

1、未初始化的变量,会保存一个特殊值 undefined
2、省略var操作符的变量,会成为全局变量

  • 初始化变量
    直接给变量赋值即可,赋值的同时,并不会标记类型

  • 修改值的变化
    修改变量值的同时,修改值的类型

  • 命令特点

三 let命令

  • 定义变量
    • let 变量名 = 值;
  • 命令特点

1、不存在变量提升
所声明的变量一定要在声明后使用

console.log(foo);//undefined
var foo = 2;

// console.log(bar);//let.js:4 Uncaught ReferenceError: Cannot access 'bar' before initialization
let bar = 3;
console.log(bar); //3

2、暂时性死区

  • 只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响
  • 在代码块内,使用let命令声明变量之前,该变量都是不可用的。在语法上称为“暂时性死区”(TDZ)
  • 本质:只要进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

3、不允许重复声明
let不允许在相同作用域内重复声明同一个变量

function a(){
    
    
    let a = 1;
    var a = 10;//Uncaught SyntaxError: Identifier 'a' has already been declared
}
a();

function b(){
    
    
    let a = 10;
    let a = 1;//Uncaught SyntaxError: Identifier 'a' has already been declared
}
b();
function func(arg){
    
    
    let arg; // Uncaught SyntaxError: Identifier 'arg' has already been declared
}
func();

function func(arg){
    
    
    {
    
    
        let arg; //正常执行
    }
}
func();

4、块级作用域

没有块级作用域导致不合理的场景:

  • 内层变量可能会覆盖外层变量

  • 用来计数的循环变量泄露为全局变量

  • 使用场景

    • for循环计数器
var a = [];
//var声明的i,在全局范围内都有效
for(var i = 0; i < 10; i ++){
    // 数组a的成员中的i指向的都是同一个i,也就是最后一轮的i值
    a[i] = function(){
        console.log(i);
    }
}

a[6]();//10

var b = [];
for(let i = 0; i < 10; i ++){
    // 变量i是let声明的,当前的i只在本来循环有效,每轮的i都是新值
    b[i] = function(){
        console.log(i);
    }
}

b[6]();//6

// for循环特点:设置循环变量的部分是一个父作用域,而循环体内部是一个单独的子作用域
// 函数内部的变量i 与循环变量i不在同一个作用域,而是有各自单独的作用域
for(let i = 0; i < 3; i++){
    let i = 'abc';
    console.log(i);// 3 abc
}

四 const命令

  • 定义变量
    声明一个只读的常量
  • 初始化变量
    const一旦声明常量,就必须立即初始化,不能留到以后赋值
  • 修改值的变化
    • 保证的不是变量的值不得改动,而是变量指向的那个内存地址不得改动
const foo = {
    
    };

foo.prop = 123;
console.log('foo.prop: ', foo.prop);//123

foo = {
    
    };
console.log('foo: ', foo);//Uncaught TypeError: Assignment to constant variable
  • 当地址指向一个对象,不可变的只是这个地址,不能把变量指向另一个地址,但对象本身是可变的,依然可以为其添加新属性
const c = [];
c.push('hello');
c.length = 0;
console.log('c: ', c); // []
c = ['dave'];
console.log('c: ', c);// Uncaught TypeError: Assignment to constant variable
  • 命令特点
    • 声明只读常量
    • 变量指向的内存地址不得改动

Guess you like

Origin blog.csdn.net/xiaoyangzhu/article/details/121151544