JavaScript普通函数调用与闭包调用差异
今天是2022年2月4号,新年假期已经过去了七分之四,这几天杭州的天气xue微的不太好,阴天下雨的都持续一个月了,最近也下了几场小雪。
今天三喜临门,首先时女朋友的生日,然后也是2022年北京冬奥会开幕式,还是一个新的节气—立春。从今天开始,新的一年慢慢步入正规。
今天总结下普通函数的调用和闭包调用。
-
概念
- 函数执行时,每个执行上下文中都会有一个包含其中变量的对象。
- 【变量对象】全局上下文中叫变量对象,它会在代码执行期间始终存在。
- 【活动对象】函数局部上下文中的叫活动对象,只在函数执行期间存在。
- 作用域链的理解
-
普通函数执行
-
function compare(value1,value2){
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
let result = compare(5,10);
-
上面示例中时一个日常使用的类型----暂且称为普通函数
- 在创建compare()函数时,就会预装载全局变量对象(compare,result)(保存在函数的的[[Scope]]属性中)。(像手机预装载软件一样,一出厂就有)
- 调用compare()函数时,会创建相应的执行上下文,并创建作用链(通过复制函数的[[Scope]]属性)
- 然后,会创建compare()函数的活动对象(arguments,value1,value2),并将其推入作用域链的前端
- 函数内部的代码在访问变量时,就会使用给定的名称从作用域链中查找。compare()函数,先访问活动对象,如果自己没有找到,再访问变量对象。
- 函数执行完后,局部活动对象会被销毁,内存中就只剩下全局作用域。
-
闭包执行
-
function createComparisonFunction(propertyName){
return function(object1,object2){
let value1 = object1[propertyName];
let value2 = object2[propertyName];
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
}
-
闭包函数的执行流程
- 调用createComparisonFunction()后,返回匿名函数,此时的作用域包含全局上下文的变量对象和当前函数的活动对象。匿名函数就可以访问作用域链中的所有变量
- createComparisonFunction()执行完后,其执行的上下文作用域链会销毁。但是它的活动对象会保存在返回的匿名函数的作用域链中(和正常函数的差别)。直到匿名函数执行完后才会销毁。
- 闭包导致的问题
- 闭包会保留它们包含函数的作用域,所以比其他函数更占内存。
|