开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
闭包
闭包是指那些引用了另一个函数作用域中变量的函数,通常实在嵌套函数中实现的
function createComparisonFunction(propertyName) {
return function (object1, object2) {
// 下面两行代码引用了外部函数的变量 propertyName
let value1 = object1[propertyName];
let value2 = object2[propertyName];
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
};
}
函数执行过程中作用域链的变化
函数执行时,每个执行上下文都会有一个包含其中变量的对象
执行上下文
执行上下文是评估和执行
JavaScript代码的环境的抽象概念。 JavaScript 代码在运行时,都是在执行上下文中运行的。
执行上下文的类型
执行上下文存在三种类型
-
全局执行上下文: 这是默认的上下文,任何不再函数内部的代码都在全局上下文中。他会执行两件事: 创建一个全局对象 (在浏览器中为
window对象,在node环境下为global对象),并且设置this 指向这个全局对象; 一个程序中有且只有一个全局执行上下文 -
函数执行上下文: 每当一个函数被调用是,都会为这个函数创建一个新的执行上下文。每个函数都有他自己的执行上下文。函数执行上下文可以有任意多个。每当创建一个函数执行上下文是,都会按照一定的顺序执行一系列步骤
-
Eval 函数执行上下文: eval 函数内部的代码会有属于它自己的执行上下文。
function compiler(value1, value2){
if(value1 > value2){
return 1
}else if(value1 < value2){
return -1
}else{
return 0
}
}
let result = compiler(1,10)
执行上下文建立步骤
-
- 创建阶段
- 创建阶段
-
- 创建作用域链
- 创建作用域链
-
- 创建活动对象
创建活动对象后,会将对用对象推入作用域链的最前端
- 创建活动对象
创建活动对象后,会将对用对象推入作用域链的最前端
-
- 执行代码
this 对象
在闭包中使用 this 会变得复杂。如果内部函数没有使用箭头函数定义,则内部函数的 this 对象会在运行是绑定到函数的执行上下文中。在全局中调用,非严格模式下, this 只想 window,严格模式下,this 为 undefined
立即调用的函数表达式
立即调用匿名函数又被成为立即调用的函数表达式(IIFE)。
// 立即调用函数
(function(){})()
使用 IIFE 锁定参数值
let divs = document.querySelectorAll('div');
// 达不到目的!每次点击打印都为 divs.length
for (var i = 0; i < divs.length; ++i) {
divs[i].addEventListener('click', function() {
console.log(i);
});
}
使用 IIFE 解决上述问题
let divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; ++i) {
divs[i].addEventListener('click', (function (frozenCounter) {
return function () {
console.log(frozenCounter);
};
})(i));
}