每个函数存在一个[[Scope]]
内部属性,包含了一个函数被建立得做用域中对象得集合,这个集合为函数得做用域链。例以下面的全局函数:闭包
fucntion add(num1, num2){ var sum = num1 + num2; return sum; }
当函数add
被建立时,它的做用域链中便插入了一个对象变量,里面包含全部在全局范围内定义的变量。
函数add
的做用域会在函数执行时用到,函数每次执行都会建立一个执行环境
的内部对象,每一个执行环境都有本身的做用域链。函数运行时,一个被称为活动对象
的新对象就为执行环境建立好了,里面包含了函数的全部局部变量,命名参数,参数集合以及this。假设执行var total = add(5,10)
,其对应的做用域链以下:
函数执行过程当中,变量的查找时从做用域头部开始查找,若是找到就是使用改变量的值。若是找不到就继续从做用域下一个对象查找,直到找到改变量。如过匹配不到,则为undefined。当频繁使用全局变量时,能够先使用一个局部变量保存起来,以后直接访问局部变量能够减小查找次数提升效率。例如:函数
function initUI(){ var doc = document, bd = doc.body, links = doc.getElementsByTagName("a"); .... }
当函数执行完成,活动对象也会随之销毁。但闭包时,活动对象并不会销毁。这也是为何闭包占用内存大的缘由。性能
资料:《高性能JavaScript》第2章节this