lexicalspcope & 闭包
作用域链
每个执行上下文中的变量环境中都包含了一个外部应用,用来指向外部引用,我们称之为outer
1 |
|
执行到bar的console时,先从bar执行环境中的词法环境中查找变量,没有则从变量环境中查找,仍然没有,
通过外部引用查找,这个outer指向了全局执行上下文,获取到myName 22
词法环境->变量环境->外部引用->全局环境的查找链,就叫做作用域链
词法作用域
词法作用域又称静态作用域,因为它是由代码中函数生成的位置决定的,与其它无关,可以预测代码执行过程中如何查找标识符
词法作用域定义了变量环境中outer 的指向
bar中外部引用根据词法作用域指向了全局执行上下文而不是foo的执行上下文
块级作用域中的变量查找
1 |
|
闭包
词法作用域规定,内部函数总是可以访问外部函数中声明的变量。
当调用一个外部函数返回内部函数,即使外部函数已经执行完了,但是内部函数引用外部函数的变量依然
保存在内存中,这些变量的集合称为闭包,只要应用在,依然可以重新建立联系
1 |
|
即使foo执行完毕,但是它返回的innerbar 对象包含了foo内部的引用,test1、myName
当执行到 bar.setName 方法中的myName = “极客邦”这句代码时,JavaScript 引擎会沿着“当前执行上下文–>foo 函数闭包–> 全局执行上下文”的顺序来查找 myName 变量,你可以参考下面的调用栈状态图
首先是setName的执行上下文中查找myName,然后在它的变量环境中通过外部引用找到foo的闭包
思考
1.变量的查找流程?
2.理解词法作用域、作用域链、闭包
3.
1 |
|
function buildLocationTree(nodeList){
var nodes = [];
var root = {
root: nodes
}
for(var i = 0; i < nodeList.length; i++){
var ele = nodeList[i];
var deep = ele.id;
if(!deep){
nodes.push(createNode(ele.id,ele.name, ele.subLocations, pid))
}else {
var target = nodes;
while(pid>0){
if(!target.subLocations){
target.subLocations = [];
}
pid--;
target = target.subLocations
}
target.push(createNode(ele.id,ele.name, ele.subLocations, pid))
}
}
return root;
}
function createNode (id, name, subLocations, pid){
return {
id,
name,
subLocations,
pid
}
}
function sort(arr){
if(arr.length < 2){
return arr
}
var arrUnit = arr[5000].timestamp;
var left = [],
right = [];
for(var i = 1; i < arr.length; i++){
if( arr[i].timestamp < arrUnit){
left.push(arr[i]);
}else {
right.push(arr[i]);
}
}
return sort(left).concat(arrUnit,sort(right))
}
function matchNum(str){
return str.match(/uin=\D*(\d+)/)[1];
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!