ES6新特性:块级作用域let和const

ES6是ECMAscript6.0的简称;是js语言的一个标准,是一个规范。用于复杂、大型应用程序、企业级的开发
块级作用域let

var 是一个函数作用域

function a(){

    if(true){

        var str="aa";

    }

console.log(str);

}

a();//aa

 

只要在 a()这个函数体内,var 声明的str变量里的值都可以被取到

 

var aa="11";

var aa="22";

console.log(aa);//22

 

let 是一个块级作用域

必须要先声明再使用

function a(){

    if(true){

        let str="aa";

        console.log(str);

    }   

    console.log(str); 

}

a();

脱离了if块之后,let生命的str变量将无法被取到,第二个console.log会报错,str未被定义,第一个console.log打印出aa

 

let aa="11";

let aa="22";

console.log(aa);//报错显示aa已经被定义

 

两者区别根本原因:

let不会存在变量提升,而var存在

console.log(str);

var str="aa"//undefined

let str="aa";//报错  str没有被定义

 

for(var i=0;i<5;i++){

}

console.log(i);//5 通过var 声明 i变量提升变为全局变量

 

for(let i=0;i<5;i++){//let只在括号内有用处

}

console.log(i);//let不存在变量提升 所以会报错 i未被定义

js是浏览器边解析边执行,解析器会优化代码,

谷歌V8引擎扫描函数体时,会对var优先执行,导致变量提升

 

暂时性死区(没有被定义的时候就可能被用到)

var str="aa";

if(true){

    str="123";

    let str;//str没有被let定义赋值

}

 

var x=y,y=2;

function a(){

    console.log(x,y);//undefined 2

}

 

let x=y,y=2;

function a(){

    console.log(x,y);//报错:y没有被定义

}

a();

 

函数内部重新声明参数

function fun(i){

    //let i; 这种方法不可取

    if(true){

        let i="as";

    }

};

let str="111";

if(true){

    let str="112";

    console.log(str);//112

}

console.log(str);//111

 

var str="qq";

function  fun(){

    console.log(str);//undefined

    if(false){

        var str="ww";

    }

}

//函数内部存在变量提升,其实代码就是:

 

var str="qq";

function  fun(){

    var str;//对str 只声明没有定义

    console.log(str);//undefined

    if(false){

        var str="ww";

    }

}

 

let str="112";

function fun(){

    console.log(str);//undefined

    if(false){

        let str="113";

    }

}

符合预期的 for 循环

for(var i=0;i<3;i++){

    setTimeout(function(){

        console.log(i);//3

    },10)

}

 

for(let i=0;i<3;i++){

    setTimeout(function(){

        console.log(i);//0 1 2

    },10)

}

可以看到在 for 循环中使用 let 方式声明变量才是符合预期。

在 for 中每一次循环,let 都是重新声明变量,并且因为 JavaScript 引擎会记住上一次循环的值,初始化 i 时在上一轮的基础上计算。

可以看到在 for 循环中至少有两层作用域,看下面的例子更容易理解。

for (let i = 0; i != 3; i++) {

 let i = 'seven';

 console.log(i);

}

console.log('eight');

// 依次打印

seven

seven

seven

eight

 

 const声明一个只读的常量,常量的值不能被改变

const类似于let,let是未赋值不能被调用,const会直接报错

不能只声明不赋值,一旦声明变量,必须初始化,不能以后赋值操作

const str={};

str.name="xiaobai";

str.action=function(){

    consoole.log(this.name);

}

str={};

str.action()//报错

const 声明的变量必须设置初始值,且不能重复赋值。

 

const c3 = 'c3';

let l3 = 'l3';

var v3 = 'v3'; 

console.log(c3, l3, v3);

// 输出 c3 l3 v3

 

c3 = 2; // Uncaught TypeError: Assignment to constant variable

l3 = 2;

v3 = 2;

console.log(c3, l3, v3);

// 输出 c3 2 2

 

 

const c32;

// 报错

// Uncaught SyntaxError: Missing initializer in const declaration

 

 

const 定义常量,该常量不能赋值,但该常量的属性可以赋值

不能赋值其实就是它的指向不允许被修改

const str={};

const ary=[];

str.name="223";

ary.push("3");

console.log(str);//{name: "223"}

console.log(ary);//["3"]

 

// 禁止给对象赋值,应该使用 Object.freeze

const c233 = Object.freeze({});

const c234 = Object.freeze([]);

c233.name = 'seven';

 

// 普通模式下不报错

// 严格模式下报错

// Uncaught TypeError: Cannot add property name, object is not extensible

 

c234.push(27);

 

// 普通模式下就会报错

// Uncaught TypeError: Cannot add property 0, object is not extensible

 

console.log(c233, c234);

 

// Uncaught TypeError: Cannot add property name, object is not extensible

 

全局变量不再设置为顶层对象(window)的属性,有效避免全局变量污染

const c24 = 'c24';

let l24 = 'l24';

  

console.log(c24, l24);

// 输出 c24 l24

  

console.log(window.c24, window.l24);

// 输出 undefined undefined

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值