@1 首先来了解下var与let/const内存存储的机制:
在全局下用var声明的变量,存储在全局(Global-GO)中,也就是window。 let const声明的变量。存储在脚本中(script-VO)。
我们在全局访问 console.log( a ) // 首先我们会出脚本中寻找是否存在a,如果a不存在会去全局window下进行查找,如果都不存在的话就会报错。
@2 我们再来看一道面试题 来研究下函数的底层执行逻辑
let x = [ 12 , 23 ]
const fn = function (y) {
y[0] = 100
y = [100]
y[1] = 200
console.log(y)
}
fn(x)
console.log(x)
首先我们来看一下函数执行数据存储的过程:
函数是一种特殊的对象【可执行对象】;函数(普通函数 构造函数)对象;
创建函数: 1 开辟堆内存空间【16进制地址】2 存储信息:在函数声明的时候声明了作
用域在哪个上下文创建的,其作用域就是谁【宿主环境】,函数体内的代码
当做字符串存储起来,看做普通对象存储键值对name:函数名 length:形参个
数 prototype原型对象 _proto_原型链,3 把空间地址赋值给变量【函数名】
函数执行: 1 创建一个全新的私有执行上下文+EC(?)再加上私有的变量对象AO(?)。
2 代码执行之前,需要初始化作用域链《私有变量和上下文变量》,初始化
This,初始化arguments,形参赋值【私有变量->AO】,变量提升。
3 代码执行
4 关于上下文的回收释放问题,一般情况下函数执行万,所形成的的私有上
下文会被释放掉
作用域链: 规划出变量查找的过程
私有上下文中遇到一个变量,首先看是否是自己私有的,如果是,接下来
对变量的操作都是私有的,如果不是私有的,基于作用域,去上级上下文中
进行查找,如果还找不到继续向上找到全局window为止。
@3 var没有块级作用域,let/const 存在块级作用域:
console.log(a) // undefiend 因为var a 存在变量提升的问题
var a = 12
var b = 13
if(1===1) { // 判断语句中有作用域和执行上下文 var声明的是全局变量 let/const是私有变量,
console.log(a) // 12
var a = 100 // 全局的a
var b = 200 // 判断体内私有的b
console.log(a) // 100
console.log(b) // 200
}
console.log(a) // 100
console.log(b) // 13
@4 再来看另外一个面试题吧: