解析 var let const 区别 以及内部实现过程

131 阅读3分钟

var let const 声明变量

  1. var可以重复定义相同的变量名 let const不可以重复定义 2.** var 有作用域的提升 let/cons没有作用域的提升** 解析: let 和 const 在执行上下文解析期间就会被创建出来,但是没有进行作用域的提升 所以无法在创建前使用 所以说在编译期间let 和const 声明的变量它是有创建出来的 3.let const 没有添到window里面 并且保存的位置也是不一样的 解析: var 声明的变量它是会添加到winodw里的 并且他会存在全局环境变量记录的 在早起ECMA3规范中对描述执行上下文中 每一个执行上下文都会关联一个环境变量(varile object)简称Vo,在源代码里面的变量和函数声明包括函数的参数 都会被作为属性加入Vo中 在近期修改过的ECMA规范中描述执行上下文 每一个执行上下文都会关联一个环境变量(variable Evironment)简称Ve,在源代码里面的变量和函数声明包括函数的参数 都会被作为环境记录加入Vo中 V8引擎会根据新规范 在执行上下文中 创建一个VE 叫做variables_:VariableMap(也就是哥HashMap类型,为了支持声明的变量和查找):里面也会储存定义的全局变量 但是在早起VO和浏览器的window是一个对象(VO=window) 但是现在window是一个单独的对象 因为为了适配以前的代码用var声明的变量也会加入window里 但是let和const不会了
// let bar = "bar"

// const constant(常量/衡量)
// const name = "abc"
// name = "cba"

// 注意事项一: const本质上是传递的值不可以修改
// 但是如果传递的是一个引用类型(内存地址), 可以通过引用找到对应的对象, 去修改对象内部的属性, 这个是可以的
// const obj = {
//   foo: "foo"
// }

// // obj = {}
// obj.foo = "aaa"
// console.log(obj.foo)


// 注意事项二: 通过let/const定义的变量名是不可以重复定义
// var foo = "abc"
// var foo = "cba"

let foo = "abc"
// SyntaxError: Identifier 'foo' has already been declared
let foo = "cba"

console.log(foo)
// console.log(foo)
// var foo = "foo"

// Reference(引用)Error: Cannot access 'foo' before initialization(初始化)
// let/const他们是没有作用域提升
// foo被创建出来了, 但是不能被访问
// 作用域提升: 能提前被访问
console.log(foo)
let foo = "foo"

const本质上的值是不可以修改的 但是如果传递的是一个引用类型(内存地址)可以通过找到对应的对象 修改对象内部属性

const obj={foo:'foo'}
obj.foo='sss'

块级作用域

es5 里面没有块级作用域 在es5只有 全局作用域 和函数作用域 在es6中的块级作用域 对var声明的变量是无效的 ifelse swich都是有块级作用域的 但是function在大多数浏览器还可以在外部访问到的 因为为了兼容以前的代码 所以做了特殊处理 关于for循环 如果用var来声明的变量 因为var是没有块级作用域所以在循环内部获取不到每一次循环的值 用const也不能声明 因为conts声名的值不可以改变

const names = ["abc", "cba", "nba"]

// 不可以使用const
// for (let i = 0; i < names.length; i++) {
//   console.log(names[i])
// }

// {
//   let i = 0
//   console.log(names[i])
// }

// {
//   let i = 1
//   console.log(names[i])
// }

// {
//   let i = 2
//   console.log(names[i])
// }

// for...of: ES6新增的遍历数组(对象)
for (const item of names) {
  console.log(item)
}

// {
//   const item = "abc"
//   console.log(item)
// }

// {
//   const item = "cba"
//   console.log(item)
// }

// console.log(item)