写在前面
用ES5实现块级作用域
什么是作用域?
- 作用域是指程序源代码中定义变量的区域
- 作用域规定了如何查找变量,也就是确定当前执行代码对变量的权限
- javascript和大多数语言一样采用词法作用域
编译阶段
- 通过 var 声明的变量,会提升到函数变量环境中
- let、const 声明的变量会被推入词法环境中
- 在代码块内,通过 let、const 声明的变量,既不会推入变量环境,也不会推入词法环境。
执行阶段
- 代码执行到代码块,在代码块内,通过 let、const 声明的变量会被推入到词法环境,因此在代码块内这些变量是可访问的
- 当代码块执行结束时,在代码块内,通过 let、const 声明的变量会从词法环境中推出,因此在代码块外访问不到这些变量
实现let
通过立即执行函数实现
var a = 2;
(function(){
var a = 3;
console.log(a); //3
})()
console.log(a)//2
实现const
通过Object.defineProperty(obj, prop, description)
实现
因为ES5没有block的概念,因此无法完全实现const,主要挂载到某个属性下就好了,因此这个容器:无论是全局
javascript中的全局对象window,还是自定义的object
function _const(data, value) {
Object.defineProperty(window, data, {
enumerable: false, //是否可以被for-in循环访问属性,也就是能否在对象上定义属性。
configurable: false,//是否可以被删除
get: function() {
return value;
},
set: function() {
throw new TypeError('Assignment to constant variable.');
}
})
}
const注意事项
const保证的并不是变量的值不许改动,而是变量执行指向的内存地址所保存的数据不许改动。
- 对于基础类型的值,值保存在指向内存地址中
- 对于复杂类型的数据,保存在指向的内存地址的指针,const保证这个指针是固定的,但是数据结构不保证固定。