let,var,const

letconst块级声明用于声明在指定块作用域之外无法访问变量。let 用于声明变量, const 用于声明不可改变的常量,const复杂类型对象等的可以改变属性
立即执行函数的组成

定义一个函数
将整个函数包裹在一对括号中
将函数声明转换为表达式
在结尾加上一对括号
让函数立即被执行
(function () {
    console.log("app")
})()
源代码
var a = 2;
{
  let a = 3;
  console.log(a); // 3
}
console.log(a); // 2

babel 转换后的代码
var a = 2;
{
  var _a = 3;
  console.log(_a); // 3
}
console.log(a); // 2


通过立即执行函数实现 let
var a = 2;
(function () {
  var a = 3;
  console.log(a); // 3
})();
console.log(a); // 2

基于 object.defineProperty(obj,prop,desc) 实现 const
由于 ES5 环境没有 block 的概念,所以是无法百分百实现 const,只能是挂载到某个对象下,要么是全局的 window,要么就是自定义一个 object 来当容器
function _const(data, value) {
  Object.defineProperty(window, data, {
    enumerable: false,
    configurable: false,
    get: function () {
      return value;
    },
    set: function (data) {
      throw new TypeError("Assignment to constant variable.");
    },
  });
}
_const("a", [1, 2]);
a = [3, 4]; // 报错
a.push(3);
let 用来声明局部变量

1.没有变量提升

必须 等let声明语句执行完之后,变量才能使用

2.暂时性死区

var a = 100;

if(1){    
a = 10;    //在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,    
// 而这时,还未到声明时候,所以控制台Error:a is not defined    
let a = 1;
}

3.变量不能重复声明
4.块级作用域 只在let命令所在的代码块内有效
5.非常适合用于 for循环内部的块级作用域


var.png

let.png

6.用let定义块级作用域变量

JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
{ 
  var i = 9;
} 
console.log(i);  // 9

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

var

1.定义的变量,作用域是整个封闭函数,是全域
2.变量提升:不论通过var声明的变量处于当前作用域的第几行,都会提升到作用域的最顶部
3.var声明的变量会挂载在window上,而let和const声明的变量不会

const

1.const用来专门声明一个常量
2.它跟let一样作用于块级作用域,没有变量提升,重复声明会报错
3.不同的是const声明的常量不可改变声明时必须初始化赋值),不能使用null占位。
4.声明后不能再修改 (保证变量指向的内存地址所保存的数据不允许改动)
5.如果声明的是复合类型数据,可以修改其属性

复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const只能保证指针固定的,至于指针指向的数据结构变不变就无法控制了,所以使用const 声明复杂类型对象时要慎重

如果定义声明之后没有赋值,都会返回undefined

使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值

变量声明提升
console.log('1',v1);
var v1 = 100;
function foo() {
    console.log('2',v1);
    var v1 = 200;
    console.log('3',v1);
}
foo();
console.log('4',v1);
// 1 undefined  2 undefined  3 200   4 100

函数声明的优先级高于变量声明的优先级,并且函数声明和函数定义的部分一起被提升。

(I)函数式声明
console.log(foo)  =>//function foo(){console.log("test")}
function foo(){
    console.log("test")
}
(Ⅱ) 字面量声明
console.log(foo)  =>//undefined
var foo = function(){
    console.log('test')
}

你可能感兴趣的:(let,var,const)