zoukankan      html  css  js  c++  java
  • let 与var对比 ,const简介

    1.var 定义的变量 会进行变量提升:

           如果变量声明在函数里面,则将变量声明提升到函数的开头

           如果变量声明是一个全局变量,则将变量声明提升到全局作用域的开头

    即只要定义了 即使在定义之前使用也不会报错 ,而let 定义的不会,在定义之前使用将会导致报错

    console.log(k)
    console.log(x)
    let x = 10
    var k = 'ddd'
    

    console将打印

         undefined

         Uncaught ReferenceError: Cannot access 'x' before initialization

    在ES6中 使用 LexicalEnvironment(词法环境) 来储存(let、const)

    VariableEnvironment (变量环境) 组件存储(var),在 ES6 中,词法 环境和 变量 环境的区别在于前者用于存储**函数声明和变量( let 和 const )绑定,而后者仅用于存储变量( var )**绑定。

    注 . JS中的变量提升正是变量环境引起的,在创建阶段函数声明被存储在环境中,变量被设置为undefined(由于创建阶段在执行阶段之前)所以var 声明的变量在声明之前就可以访问,其值为变量环境设置的undefined 

           详见:https://muyiy.cn/blog/1/1.1.html#%E5%88%9B%E5%BB%BA%E9%98%B6%E6%AE%B5 

    2.var 只有全局作用域和局部作用域之分,而let定义块级作用域 

    for (var j = 0; j < 10; j++) {
       setTimeout(function() {
          console.log(j)
       })
    }
    //   10个10
    //  下面可以正常访问 会污染全局变量
    console.log('-------', j)
    console.log('-------', window.j)
    
    for (let i = 0; i < 10; i++) {
       setTimeout(function() {
          console.log(i)
       })
    }
    //   0---9分别被打印
    //   下面报错Uncaught ReferenceError: i is not defined
    console.log('-------', i)

    注意var 定义的全局变量会自动添加到window上作为对象的属性,就像js的全局函数可以通过window访问一样

         在控制台打印window 可以展开看 j 是 10 被挂载到了window上

         js的全局方法 escape(),eval(),isNan(),isFinite(),parseFloat(),parseInt(),unescape();都可以通过window访问,这样我们往往会将window的自身方法和js的全局方法混淆了

    3. var 可以被重新定义和赋值而let不行 对let进行重新赋值将会报错

    let x = 10
    
    let foo = () => {
          console.log('------------', x)
          // 不能被重新定义 下面将会报错
          let x = 20
          x++
    }
    // 不能被重新定义 下面将会报错 不论全局还是局部
    let x = 1
    foo()
    var k = '444'
    var k = 'kjk'
    console.log(k) //可以正常输出
    

    4 const 同let相同是块级作用域 

    const声明一个只读的常量,一旦声明,常量的值就不能改变,这意味着,const一旦声明常量,就必须立即初始化,不能等到之后再赋值。因此,改变常量和只声明不赋初始值都会报错。

    const的作用域与let命令相同,只在声明所在的块级作用域内有效。

    if (true) {
    	const i = 1;
    }
    console.log(i); //报错

    我们理解的是const定义的是常量,但是const定义对象是锁定的是对象的地址而不是本身对象的值,就对象属性可以被改变 ;const定义的对象做为形参时也会被修改内容;

    const aaa = 1
    const ttt = {k:111}
    ttt.k = 222
    console.log(ttt) //{k:222}
    aaa = 3  //Uncaught TypeError: Assignment to constant variable.

    注:当请整个对象都被锁定可以使用Object.freeze(),该方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,

           不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。 freeze() 返回和传入的参数相同的对象。

          var obj = {
            prop: 42
          };
          // 作为参数传递的对象与返回的对象都被冻结
          // 所以不必保存返回的对象(因为两个对象全等)
          var oo = Object.freeze(obj);
    
          console.log(oo=== obj) //true
    
          // 添加属性将不做任何事情,严格模式下会报错;
          obj.pars = 1
          // 修改属性 也不会器作用,严格模式下会报错;
          obj.prop = 33;
          console.log(obj); //42
    

    可以理解为 const 锁定的是 栈,Object.freeze 锁定的是 堆和栈;

  • 相关阅读:
    jstl插件使用
    IDEA配置tomcat
    Spring框架
    2020/7/17 JAVA模拟斗地主发牌洗牌
    2020/7/15 JAVA之Map接口
    2020/7/14 Java之增强for循环、泛型、List接口、Set接口
    2020/7/13 集合之ArrayList集合、Collection接口、Iterator迭代器
    2020/7/13 常用API之基本类型包装类、System类、Math类、Arrays类、大数据运算
    2020/7/11 日期相关类
    2020/7/8 JAVA总结之:匿名对象/内部类/包的声明与访问/访问修饰符/代码块
  • 原文地址:https://www.cnblogs.com/xhliang/p/11971704.html
Copyright © 2011-2022 走看看