精华内容
下载资源
问答
  • let和var的区别

    2021-04-10 11:48:22
    介绍ES6中引入的let和var的区别

    很多人搞不懂Let和Var变量的区别,现总结一下。

    let是在ES6中引入的

    ES6 新增了let命令,用来声明局部变量;

    它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

    先看个var的常见变量提升的面试题目:

    var a = 99;            // 全局变量a
    f();                   // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 
    console.log(a);        // a=>99,  此时是全局变量的a
    function f() {
      console.log(a);      // 当前的a变量是下面变量a声明提升后,默认值undefined
      var a = 10;
      console.log(a);      // a => 10
    }
    

    // 输出结果:

    undefined
    10
    99
    

    ES6可以用let定义块级作用域变量;

    在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围;

    例如:

    { 
      var i = 9;
    } 
    console.log(i);  // 9
    

    ES6新增的let,可以声明块级作用域的变量。

    { 
      let i = 9;     // i变量只在 花括号内有效!!!
    } 
    console.log(i);  // Uncaught ReferenceError: i is not defined
    

    let 配合for循环的独特应用

    let非常适合用于 for循环内部的块级作用域;

    JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响;

    看一个常见的面试题目:

    for (var i = 0; i <10; i++) {  
      setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
        console.log(i);        // 执行此代码时,同步代码for循环已经执行完成
      }, 0);
    }
    // 输出结果
    1010// 这里面的知识点: JS的事件循环机制,setTimeout的机制等
    

    如果把 var改成 let声明:

    // i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
    for (let i = 0; i < 10; i++) { 
      setTimeout(function() {
        console.log(i);    //  i 是循环体内局部作用域,不受外界影响。
      }, 0);
    }
    // 输出结果:
    0  1  2  3  4  5  6  7  8 9
    

    let没有变量提升与暂时性死区

    用let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用,不然会报Uncaught ReferenceError错误。

    例如:

    console.log(aicoder);    // 错误:Uncaught ReferenceError ...
    let aicoder = 'aicoder.com';
    // 这里就可以安全使用aicoder
    

    ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

    总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区(temporal dead zone,简称 TDZ)。

    let变量不能重复声明

    let不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier ‘XXX’ has already been declared

    例如:

    let a = 0;
    let a = 'sss';
    // Uncaught SyntaxError: Identifier 'a' has already been declared
    

    总结

    ES6的 let 让 js真正拥有了块级作用域,也是向这更安全更规范的路走,虽然加了很多约束,但是都是为了让我们更安全的使用和写代码。

    展开全文
  • let var 的区别

    2019-09-26 16:53:38
    最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别。我简单总结一下,以便各位以后面试中使用。 ES6 新增了let命令,用来声明局部变量。它的用法类似于var...

    let 和 var 的区别

    最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别。我简单总结一下,以便各位以后面试中使用。

    ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

    先看个var的常见变量提升的面试题目:

    题目1:
    var a = 99;            // 全局变量a
    f();                   // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 
    console.log(a);        // a=>99,  此时是全局变量的a
    function f() {
      console.log(a);      // 当前的a变量是下面变量a声明提升后,默认值undefined
      var a = 10;
      console.log(a);      // a => 10
    }
    
    // 输出结果:
    undefined
    10
    99
    
    

    ES6可以用let定义块级作用域变量

    在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
    例如:

    { 
      var i = 9;
    } 
    console.log(i);  // 9
    
    

    ES6新增的let,可以声明块级作用域的变量。

    { 
      let i = 9;     // i变量只在 花括号内有效!!!
    } 
    console.log(i);  // Uncaught ReferenceError: i is not defined
    
    

    let 配合for循环的独特应用

    let非常适合用于 for循环内部的块级作用域。JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响。看一个常见的面试题目:

    for (var i = 0; i <10; i++) {  
      setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
        console.log(i);        // 执行此代码时,同步代码for循环已经执行完成
      }, 0);
    }
    // 输出结果
    10   共10个
    // 这里面的知识点: JS的事件循环机制,setTimeout的机制等
    
    

    如果把 var改成 let声明:

    // i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
    for (let i = 0; i < 10; i++) { 
      setTimeout(function() {
        console.log(i);    //  i 是循环体内局部作用域,不受外界影响。
      }, 0);
    }
    // 输出结果:
    0  1  2  3  4  5  6  7  8 9
    
    

    let没有变量提升与暂时性死区

    let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用,不然会报Uncaught ReferenceError错误。
    例如:

    console.log(aicoder);    // 错误:Uncaught ReferenceError ...
    let aicoder = 'aicoder.com';
    // 这里就可以安全使用aicoder
    
    

    ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
    总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

    let变量不能重复声明

    let不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier 'XXX' has already been declared

    例如:

    let a = 0;
    let a = 'sss';
    // Uncaught SyntaxError: Identifier 'a' has already been declared
    
    

    总结

    var 存在变量提升 ,内部会收外部变量影响 ; 可以在同一个相同作用域,多次声明同一变量,以最近的声明为准。。。。(看清 是最近 不是最后)

    let 不存在变量提升,一个相同作用域只能声明一次, 存在类似于块级作用域 的作用域。

    ES6的let让js真正拥有了块级作用域,也是向这更安全更规范的路走,虽然加了很多约束,但是都是为了让我们更安全的使用和写代码。

    展开全文
  • let var const var关键字 var关键字用法 js中声明变量关键字。 var num = 1; 如果在函数作用域中声明,为局部变量;如果在全局中声明,则为全局变量。 num = 2; 这种写法实际上是赋值,如果在函数作用域中赋值...

    let var const

    var关键字

    var关键字的用法

    js中声明变量的关键字。

    var num = 1;
    

    如果在函数作用域中声明,为局部变量;如果在全局中声明,则为全局变量。

    num = 2;
    

    这种写法实际上是赋值,如果在函数作用域中赋值就会去找当前函数作用域中的num,如果当前作用域中没有这个变量就会接着去上一个作用域中寻找,直到找到全局,在全局中如果也并没有声明过这个变量,就会给全局对象window强行添加一个num属性进行赋值。

    var关键字的缺点

    1) var会被声明提前,会打乱程序原本的执行顺序(变量提升传送门

    2) 在ES6之前,js中没有块级作用域,代码块内的变量,极有可能影响到外部的变量。

    let关键字

    ES6中新增的专门代替var用来声明变量的关键词。

    优点:

    1. 不会声明提前

    2. 将js中的程序块变成了一级作用域

    原理:

    1. 从let位置开始,到当前代码块底部,自动建立了匿名函数自调

    2. let在底层还悄悄的修改了内部的变量名: 比如:let t -> let _t

    注意:

    1. 相同作用域中不能let两个同名的变量

    2. let之前不允许提前使用该同名变量

      let生成匿名函数自调是从let位置才开始包裹,let之前的代码不属于匿名函数自调内部,所以无法访问匿名函数内的变量;

      ES6中明确规定如果块级中存在letconst命令时,则这个区块对这些命令声明的变量从一开始就形成封闭的区域,在代码块内,使用let命令前,该变量都是不可用的,这块区域在语法上称为“暂时性死区“

    3. 即使在全局let的变量,也不会保存在window

      实际上保存在了let原理中提到的立即执行匿名函数自调函数的函数作用域中;

      ES6在这方面也有规定:varfunction命令声明的全局变量依旧是顶层对象的属性,而letconstclass命令声明的全局变量不属于顶层对象的属性;也就是说从ES6开始,全局变量逐步于顶层对象的属性隔离。

    let和for循环的化学反应

    //1.
    for(var i = 0; i < 5 ;i++){
    	setTimeout(function(){
    		console.log(i)
    	},500)
    }
    //55555
    //2.
    for(let i=0; i < 5 ;i++){
    	setTimeout(function(){
    		console.log(i)
    	},500)
    }
    //01234
    

    第一题因为定时器是异步任务,会加入到任务队列等待主程序执行完毕在执行。主程序执行循环,当i等于5时,循环条件不满足退出循环,主程序结束,开始执行任务队列中的定时器对象,定时器对象中没有自己局部的i就会去上级作用域中拿,而上级的i主程序结束后就变成了5,所以会输出55555

    实际上第二题在程序中可以看成下面这样运行的(看上边所说的let的原理):

    for(var i=0; i < 5 ;i++){
        (function(i){//外层函数  i为要保护的变量
           setTimeout(function(){//内层函数
    			console.log(i)
    		},500) 
        })(i)
    }
    

    看以上代码,其实就是一个闭包(闭包传送门),每循环执行一次就会生成一个定时器对象并且匿名函数自调中的局部变量 i 都会因为被内层函数中连着无法释放,每次都会生出一个闭包保存当次的 i 的值。当主程序执行结束后,执行任务队列中的定时器对象,定时器对象中没有自己的局部 i 就会去上层找,找到的就是每次匿名函数生成的作用域对象中的 i ,所以输出是01234

    const关键字

    ES6中新增的专门用来声明常量的关键词。

    let的特性const都有,不能反复声明,存在块级作用域,不存在变量提升,也有暂时性死域的特点。

    let区别在于:

    1. const一旦声明就必须赋值;

    2. const声明如果是一个原始类型的常量,一旦声明就无法修改;

    3. const声明如果是一个引用类型的常量,一旦声明,保存在const中的地址值(指针)就无法修改,但是通过地址值指向的对象的属性还是能够修改的。

    const PI;
    //报错 const一旦声明就必须赋值
    const PI=3.1415926;
    PI = 3.14;
    //报错 const一旦声明如果值是原始类型的值,值不能改变
    const obj = {a:1,b:2}
    obj = {};
    //报错 const一旦声明如果值是引用类型的值,地址值不能改变
    

    var let const 对比总结:

    3个方向:1值是否能改变,2作用域在哪,3是否存在变量提升

    1. 使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象,值能修改。

    2. 使用let声明的变量,其作用域为该语句的代码块内,不存在变量提升,值能修改。

    3. 使用const声明的常量,其作用域为该语句的代码块内,不存在变量提升,且常量的值不能修改(原始类型的值和内存地址值不能修改)。

    ps: 学习阮一峰 ES6入门 个人理解心得总结(1)let,const命令 个人理解难免有错误,欢迎大家指正

    展开全文
  • Let Var Const的区别

    2020-10-21 11:32:30
    Let Var Const 的区别 1.作用域 ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念。 ES6 中新增了块级作用域。块作用域由 { } 包括,if语句 for语句里面的{ }也属于块作用域。 2. varlet、const...

    Let Var Const 的区别

    1.作用域

    ES5 中作用域有:全局作用域、函数作用域。没有块作用域的概念。
    ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。

    2. var、let、const的区别

    ①var定义的变量,没有块的概念,它可以跨块访问,但是不能跨函数访问。
    ②let定义的变量,只能在块作用域访问 ,不能跨块也不能跨函数访问。
    ③const 定义常量,使用时必须初始化(就是要赋值),只能在块作用域访问,不能跨块也不能跨函数访问,而且它的值不能修改* (第三点说明可以改的情况)*。
    下面代码效果;

    <script type="text/javascript">
    	
        {
            var a = 1;
            console.log(a); // 1
        }
        console.log(a); // 1
        // 通过var定义的变量可以跨块作用域访问到。
     
        (function A() {
            var b = 2;
            console.log(b); // 2
        })();
        // console.log(b); // 报错,
        // 可见,通过var定义的变量不能跨函数作用域访问到
     
        if(true) {
            var c = 3;
        }
        console.log(c); // 3
        for(var i = 0; i < 4; i ++) {
            var d = 5;
        };
        console.log(i); // 4   (循环结束i已经是4,所以此处i为4)
        console.log(d); // 5
        // if语句和for语句中用var定义的变量可以在外面访问到,
        // 可见,if语句和for语句属于块作用域,不属于函数作用域。
     
    </script>
    
    <script>
    //块级作用域
      { 
       var a=1;
       let b =2;
       const c =3;
       var aa;
       let bb;
       const cc;//报错
       console.log(a);//1 
       console.log(b);//2
       console.log(c);//3 
       console.log(aa);//undefinde  
       console.log(bb);//undefinde 
    }
    console.log(a);//1
    console.log(b);//报错
    console.log(c);//报错
    //不能跨跨作用域
    //函数作用域function(){
       var a=4;
       let b=5;
       const c=6;
       console.log(a);//4
       console.log(b);//5
       console.log(c);//6
    }();
    console.log(a);//报错
    console.log(b);//报错
    console.log(c);//报错
    //不能跨函数
    </script>
    

    3. const定义的对象属性可以改变的情况

    有一个问题,上面说到 const 是不能修改的,但是实际测试后发现挺特殊的,在此记录一下。

    <script>
     const Person = {
         name : 'XiaoMing',
         sex : '男'
     }
     
     person.name = 'XiaoHong'
     
     console.log(Person.name)
     </script>
    

    运行上述代码,可以发现Person对象的name属性确实被修改了,这是咋回事?

    因为对象是引用类型的,Person中保存的仅是对象的指针,这就意味着,const仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。也就是说const定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的。

    然后我们试着修改一下指针,让Person指向一个新对象,会发现它果然报错

    <script>
    const person = {
       name : 'XiaoMing',
       sex : '男'
    }
     
    person = {
       name : 'XiaoHong',
       sex : '女'}
        console.log(Person)// 报错
       </script>
    
    展开全文
  • var和let/const的区别块级作用域不存在变量提升暂时性死区不可重复声明let、const声明的全局变量不会挂在顶层对象下面const命令两个注意点:const 声明之后必须马上赋值,否则会报错const 简单类型一旦声明就不能再...
  • let var const 的区别

    2019-12-18 11:32:07
    varlet、const的区别 varlet、const 一、var声明的变量会挂载在window上,而let和const声明的变量不会: var a = 100; console.log(a,window.a); // 100 100 let b = 10; console.log(b,window.b); // 10 ...
  • let var的区别

    2019-01-07 07:37:27
    let和var的区别 var = []; for(var i = 0;i<10;i++){ a[i]= function(){ console.log(i); } } arr[6](); //10 复制代码上面代码中,变量i是var申明的,在全局范围内都有效,所以全局只有一个变量i,每一次循环...
  • es6中的let var 的区别
  • javascript中let和var的区别

    千次阅读 2019-02-22 13:50:10
    javascript中let和var的区别 程序媛萌小雪Mxx 0.12018.02.23 11:06*字数 584 let是es6中新增命令,也是用来声明变量的,可能很多小伙伴都像我一样,定义变量的时候都会用var而很少用到let,那么,let和var到底有...
  • var let const的区别

    2019-11-10 21:00:24
    var let const的区别var var声明的是一个变量 例 var a=“123” 或者 var a var 声明的值具有声明提升的作用 var 声明可以重复声明 后声明的会替换掉之前的 例 var a=1; var a=2; console.log(a) // 打印结果...
  • let var const的区别

    2019-08-17 22:43:44
    用来计数循环变量会泄露为全局变量varletlet var的比较constconst声明常量数值不能改变。const声明复合型变量。const声明后,就必须马上初始化。const只在声明所在块级作用域内有效const声明变量不存在...
  • ES6 let var 的区别

    千次阅读 2019-02-16 18:33:48
    ES6 let var 的区别 1.let声明的变量不存在变量提升,但是存在“暂时性死区”(temporal dead zone,简称 TDZ)。 2.let不允许在相同作用域内,重复声明同一个变量。 3.let作用域为代码块(每个花括号范围内为一...
  • ​​变量声明初始化在比较它们的区别之前,我们先来看一下变量声明初始化。变量声明:var declaration变量声明会引入了一个新的标识符 declaration,在 JavaScript 中,新创建的变量的默认值都是 unde...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,741
精华内容 1,096
关键字:

letvar和的区别