var 、 const 、 let 区别 以及变量作用域

1.在 const  和let推出 之前,js 使用var 声明变量,例如:

var  a = 1 ;
a = 2  ;
console.log(a);  // 2
a=function (){};
console.log(a)  // function (){}

上述js 代码片段,按照从上向下执行 , 对同一个变量a, 声明先赋值数字给a ,最后又把函数表达式赋值给a, 后面的赋值操作覆盖前面的值。

大家可以再看下面的两段代码:

console.log(a);                                           function b(){};
var a = 1;           /*   undefined    */                    var a =undefined;
console.log(b);    /* function b(){}  */         伪代码=>       console.log(a)
function b(){};                                                     a= 1 ;
console.log(window.a)    /* 1 */                             console.log(b) ; 
                                                           console.log(window.a)

这里就是变量提升起到的作用。我们在用var或者函数声明的方式定义一个变量时,这个变量的定义会提升当前作用域的最顶端,若全局声明还会挂载到window上。如上方的伪代码,  如果函数名也改为同变量名的,函数声明提升优先级高于变量声明, (上面左边代码  b 改为a可以试一下哦);

变量提升 ,会污染全局环境,如下代码, 不管condition   值是什么 ,value都会添加到全局环境。如果希望模拟块状作用域,es5 通常采用自执行函数  (function(){})();

var condition ;                                       var condition ; 
if (condition) {                                      var value ; 
   var value = 1;           伪代码 =>                     if(condition) {
         }                                                   value = 1;  
 console.log(value)  /* undefined*/                                           }
                                                            console.log(value) 

为了对变量生命周期  以及作用域的,我们使用 ES6  中  let,const定义变量的时候,并不会发生声明提升,并且只在局部(块)作用域有效; let  

1.   不存在变量提升, 声明前访问变量报错, 也即行业所说的, 存在暂时性死区;先声明再访问。

console.log(name);
const  name ='Tom';  //  Uncaught ReferenceError: Cannot access 'name' before initialization

2.  不能重复声明 ,let  可以先声明后赋值, const 声明后需要立即赋值 ;

let  b = 1;
const b = 2 ;   // Identifier 'b' has already been declared
const c   // Missing initializer in const declaration

3.    存在块状作用域,const  let 声明的全局变量不会挂载到顶层对象上  浏览器顶层对象window ,(node:global);

const   f = 888;
console.log(window.f)  //  undefined
 if(true){
const d = 555;
let e =333;
}
console.log(d);  //  Uncaught ReferenceError: d is not defined
console.log(e);  // 上方报错退出执行栈, 报错同上;

4.  const  一旦声明,值不能改变, let声明的变量值可以改变;

const 具体表现,简单类型值不能改变;

引用类型的值,变量指向的指针不能变化,只能保证指针是固定的(总是指向同一个地址),它内部的值是可以改变的, 例如对象的属性, 或者数组(pushshiftsplice等方法改变内容);

简单类型:
const p = '不能改变';
p = '报错'  //Uncaught TypeError: Assignment to constant variable.

引用类型:
const g = ['不能改动']
const g2 = {
  name: 'OBKoro1'
}
g[0] = '不报错'
g2.name = '不报错'
g = ['报错']
g2 = {
  name: '报错'
}

总结一下 :

varlet/const的区别:

  1. 块级作用域
  2. 不存在变量提升
  3. 暂时性死区
  4. 不可重复声明
  5. let、const声明的全局变量不会挂在顶层对象下面

const命令两个注意点:

  1. let可以先声明稍后再赋值,而const在 声明之后必须马上赋值,否则会报错

  2. const 简单类型一旦声明就不能再更改,复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。

  3. const  声明的变量对于维护者更友好,建议尽可能使用const

发布了16 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42317878/article/details/102869694
今日推荐