let/const块级作用域是怎样实现的?闭包是怎样实现的?this有什么设计缺陷?
分类:javascript
Javascript代码的执行
本文介绍了块级作用域的在内存上的实现与闭包的实现,在此之前需要简单了解一下JavaScript代码的执行.
编译
经过编译后,会生成两部分内容:执行上下文(Execution context)和可执行代码。
执行上下文
由变量环境和词法环境构成;分为全局执行上下文和函数执行上下文;所有的执行上下文又构成执行栈.
-
词法环境:通过let/const声明的変量存在于词法环境,即块即作用域;代码块內部定义的变量在代码块外部是访问不到的,并且等该代码块中的代码执行完成之后,代码块中定义的变量会被销毁
在词法环境内部,维护了一个小型栈结构函数内let和var声明同一个变量可以吗?暂时性死区
-
变量环境:通过var申明的变量和函数声明存在于此
变量和函数同名时:变量的声明会被忽略;同名的函数,选择最后声明的那个
执行
执行Javascrip 会存在多个执行上下文;通过栈的数据结构来管理的,执行上下文栈,又称调用栈。
执行栈
全局执行上下文,只有一份;函数执行上下文,函数执行结束之后,会被销毁
查找变量
- 从词法环境的栈顶向下查
- 变量环境中查找。
变量查找是静态的过程——编译阶段就决定,与调用没有关系
闭包:外函数返回的内函数对外函数中的变量有引用
外部函数已经执行结束
这些变量依然保存在内存,称为外函数的闭包
内存泄漏:被返回的内函数是一个全局变量,那么闭包会一直存在直到页面关闭
如何避免内存泄露:在函数作用域而不是全局作用域调用有用包的函数 等函数销毁后就会回收这块内存
闭包执行情况
对象查找
指向:指向调用方法的对象本身/指向window对象(在严格模式下this值是 undefined)
设置函数执行上下文中的this指向
this设计缺陷
- 嵌套函数中的this不会从外层函数中继承
bar函数中的this是:全局 window对象
声明一个変量self 用来保存this
也可以使用ES6中的箭头函数
- setTimeout推迟执行不合预期