ES6学习笔记1 let 和 const

let

let命令与var用法类似,用于声明变量,区别在于其声明的变量只在let命令所在的代码块中有效

for (let i=0; i<10; i++){
    //....
}

console.log(i);   //变量i未定义

在for循环中,设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域,上述i在循环的作用域中定义,因此在循环体外,let声明的i不再有效。

var命令存在“变量提升”,即函数声明和变量声明总是会被解释器悄悄地被”提升”到方法体的最顶部,因此可以在变量声明之前使用,let命令不允许出现这种状况,其声明的变量一定要在声明后使用,否则会报错。在let命令声明变量之前这段时间,变量不可被访问,称为暂时性死区

console.log(foo);   //变量i未定义
var foo = 2;

console.log(bar);   //报错
let bar = 2;
var tmp = 123;
if (true){
    tmp = 321; //报错
    let tmp;
}

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

function(){
    let a = 10;
    var a = 1;  //报错
}

ES6允许块级作用域的任意嵌套,外层作用域无法读取内层作用域的变量,而内层作用域可以定义外层作用域的同名变量

{
    {let a = 1;}
    console.log(a);   //报错
}
{
    let a = 1;
    {let a = 2;}
}

为了减轻不兼容问题,在ES6浏览器中,块级作用域中的函数声明语句的行为类似于var声明变量,会被提升到全局作用域或函数作用域的头部,同时还会提升到所在块级作用域的头部。而在其他环境中,函数声明类似于let语句。

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

在ES6浏览器中,上述代码会报错,是因为函数f()未定义

因此,由于环境导致的行为差异太大,应该避免在块级作用域中声明函数,即使需要,也应该写成函数表达式的形式

{
    let a = '1';
    let b = function(){
        return a;
    };
}

ES6块级作用域声明函数必须使用大括号,否则会报错

if (true){
    function f()
}

const

const声明一个只读常量,一旦声明,就必须初始化赋值,且不能再重新赋值

const PI = 3.14;
PI    //3.14

PI = 3;   //报错
const a;   //报错

constlet命令相同,只在声明的块级作用域有效,且不会被提升,存在暂时性死区,不可重复声明

{
    const a = 1;
}
a       //报错

const实际上保证的是变量指向的那个内存地址不得改动,对于简单类型的数据,值就保存在内存地址中,而对于对象来说,变量指向的内存地址保存的只是一个指针,因此只是保证这个指针是固定的,而对象本身可以被修改

const a = [];
a.push('hello');  //可执行
a.length = 0;    //可执行
a = ['1'];   //报错

如果真想使对象冻结,可以使用Object.freeze方法,使其变为不可篡改对象,具体可参考https://blog.csdn.net/zjw_python/article/details/80109580

顶层对象的属性

var命令和function命令声明的全局变量是顶层对象的属性,let命令、const命令、class命令声明的全局变量不属于顶层对象的属性

var a = 1;
window.a    //1

let b = 2;
window.b    //未定义

猜你喜欢

转载自blog.csdn.net/zjw_python/article/details/80796852