Skip to content

Latest commit

 

History

History
28 lines (17 loc) · 2.14 KB

闭包.md

File metadata and controls

28 lines (17 loc) · 2.14 KB

闭包

闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。

function compare(value1, value2) {
  if(value1 === value2) return 0;
  return value1 > value2 ? 1 : -1;
}

let result = compare(5, 10);

第一次调用compare()时,会为它创建一个包含arguments、value1和value2的活动对象,这个对象是作用域链上的第一个对象。而全局上下文的变量对象则是compare()作用域链上的第二个对象,其中包含this、result和compare。

函数执行时,每个执行上文中都会有一个包含其中变量的对象。全局上下文中叫变量对象,它会咋代码执行期间始终存在。而函数局部上下文中叫活动对象,只在函数执行期间存在。在定义compare()函数时,就会为他创建作用域链,预装载全局变量对象,并保存在内部的**[[Scope]]中。在调用这个函数的时候,会创建相应的执行上下文,然后通过复制函数的[[Scope]]**来创建其作用域链。接着会创建爱你函数的活动对象并将其推入作用域链的前端。

这个例子中,compare()函数执行上下文的作用域链中有两个变量对象:局部变量对象和全局变量对象。作用域链其实是一个包含指针的列表,每个指针分别指向一个变量对象,但物理上并不会包含相应的对象。

let compare = createComparisonFunction('name');
let result = compare({name: 'Nicholas'}, {name: 'Matt'});

在以上代码中,createComparisonFunction()返回匿名函数后,他的作用域链被初始化微包含createComparisonFunction()的活动对象和全局变量对象。这样匿名函数就可以访问到它能访问的全部变量对象。但是有个有意思的副作用是,createComparisonFunction()的活动对象并不能在它执行完毕后销毁,因为匿名函数中仍然保持着对它的引用。直到匿名函数被销毁后才会被销毁;这里可以把compare的值设置为等于null,会接触对函数的引用,从而让垃圾回收程序可以将内存释放掉。