1.let与const定义变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_15706743/article/details/82530218

1.let与const定义变量

1.var 和 function

var function 存在变量提升
var 只会提前声明,function既声明又定义
在全局作用域下,使用var和function声明的变量会给window增加属性

console.log(a);//hello
console.log(getA);//打印出函数
var a = 1;
function getA() {}

var a = 2;
console.log(a);
console.log("getA" in window);

2.let

console.log(a)//报错:a is not undined

let没有变量提升,因此使用console打印,并不会提示undefined,而是直接报错

  1. 使用let没有变量提升
  2. 不可以重复声明
  3. 不会给window增加属性
let a = 1;
//let a = 2;//报错:'a' has already been declared
console.log(window.a);

4.var在同一个作用域下可以多次声明同一个变量,let不可以

function b(){
  let a = 3;
  let a = 4;
}
b();
//Identifier 'a' has already been declared

5.如果用let声明过了 就不要再用var了

function b(){
  let a = 3;
    var a=4;
}
b();
//报错:变量被重复声明,如果用let声明过了 就不要再用var了

3.const

  1. 没有变量提升
  2. 不可以重复声明
  3. 不会给window增加属性
  4. const定义变量,一旦声明必须赋值
  5. const定义的是一个常量,不可以重新赋值
  6. 通过const声明的变量不能被修改,不能修改引用空间,但是可以修改内容,不能修改变量的地址
const a = {name:'zfpx'};
a.age = 9;
console.log(a);
//{name: "zfpx", age: 9}
    let a;
    console.log(a);//undefined
    //const b;//报错:Missing initializer in const declaration
    const b = 2;
    //b = 3;//报错:Assignment to constant variable.
  • 在使用var时,可以将已经声明的变量再次声明,而在let声明后,再次声明是不允许的
    • 不会给window增加属性,使用 in 来检测window的属性,是检测不到的,甚至,window对象都被允许打印出来
  • const在ES6中
    • 同let类似:没有变量提升,不可以重复声明,不会给window增加属性
    • 同时,const定义的是常量,var和let声明变量后,可以不赋值,但是const必须声明的时候就定义
    • var和let在声明和定以后,可以赋新值,但是const不允许再赋值。因为它是一个常量

4.块级作用域

  1. { }:一个{ }就是一个块级作用域
  2. 块级作用域下var和function声明的变量依然是全局的
  3. 块级作用域下let和const声明的变量是私有的,在外面是获取不到的
  4. { }如果想表示一个对象,不可以放在行首
 {
        var a = 0;
        function getA() {
            console.log("ok");
        }
        let b = 1;
    }
    console.log(a);//能够成功打印
    getA();//成功执行
    //console.log(b);//报错:b is not defined

1.for循环,if判断,创建对象的时候都会产生{}

{name:"Cyan",age:19}//这样写会报错,当做块级作用域

2.要表示一个对象千万不要放在行首

 let obj = {name:"Cyan",age:19};
({name:"Aqing",age:20})//这两种方式都可以

3.eval

console.log(eval('{name:"Aqing",age:20}'));//报错

这样会报错,因为eval会直接把字符串转换成一个{},所以我们拿括号包起来

 console.log(eval('({name:"Cyan",age:20})'));
    eval('var o = {name:"Aqing",age:20}');
    console.log(o);

4.if(){} 中的function 只会提前声明,不会定义,当if判断条件成立的时候,先给函数赋值,代码再执行

   if(1){
        var A = 1;
        function getAA() {

        }
    }
    console.log(A);
    console.log(getAA);

5.for循环

1.var 不支持封闭作用域,会声明到全局作用域上

1.函数作用域
2.全局作用域

function () {
  for (var i = 0; i < 3; i++) {
    console.log(i);
  }
};  
console.log(i);         //在外界拿到i    
console.log(window.i);//全局下的i
//0 1 2 3 3 

2.使用闭包,自执行函数

(function () {
  for (var i = 0; i < 3; i++) {
    console.log(i);
  }
})();
console.log(i);     //  i拿不到
console.log(window.i);
//0 1 2

i拿不到了,被封闭在函数内。

3.异步代码

for(var i = 0; i<3;i++){
 function (i) {
    setTimeout(function () {
      console.log(i);
    }, 1000);
  };
}

需求:,每一秒打印出i

代码执行栈先执行同步代码,把异步代码压到队列里,等待同步代码执行完,开始清空队列

此时打印的时候:3 3 3

1.闭包解决:
for(var i = 0; i<3;i++){
 (function (i) {
    setTimeout(function () {
      console.log(i);
    }, 1000);
  })(i);
}
// 0 1 2

每次的i都找自己的i

2.let解决:

let和{}配和可以产生一个作用域

let支持块级作用域声明的变量只会声明在当前作用域内

for (let i = 0; i < 3; i++) {
    setTimeout(function () {
      console.log(i);
    }, 1000);
}
console.log(i);

使用var声明的for循环中的循环值,在循环外是可以访问到的,也就是说,这个值是全局的。同时,这个值在外面访问时,是已经步长累加完的值。
使用let声明的for循环中的循环值,因为是属于块级作用域私有的,所以循环体外是访问不到的。

7.预解释问题 变量提升 用let解决这个问题

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

6.暂存死区,

如果作用域内 有这样一个变量 那么这个作用域内就会绑定这个变量,不会继续向上查找了

let a = 1;
{

  let a = 2;
     console.log(a);
}

猜你喜欢

转载自blog.csdn.net/qq_15706743/article/details/82530218
今日推荐