什么是闭包
闭包就是函数和它周围状态的引用捆绑在一起的组合
闭包的形态有哪些
1.函数作为返回值
function outerFn() {
const a = 1;
return function innerFn() {
console.log(a);
}
}
const fn = outerFn();
fn();
2.函数作为参数传递
let count;
function outerFn(fn) {
count = 1;
fn();
}
function innerFn() {
console.log(count);
}
outerFn(innerFn);
3.函数嵌套
let count = 0;
function outerFn() {
function innerFn() {
count++;
console.log(count);
}
return innerFn;
}
outerFn()()
函数嵌套引出另一个问题--立即执行函数(IIFE)
let count = 0;
(function immediate() {
if(count === 0) {
count = 1;
console.log(count);
}
})();
// 用途:js模块化的基石
闭包的用途
1.实现私有化变量
2.在模块的隔绝基础上实现了参数变量的打通与传递
this(执行上下文)
什么是执行上下文
函数在执行期间创建的一个环境,用于管理变量、作用域链、this和其他相关信息(外部环境的引用,包含闭包)
如何改变this指向
隐式绑定
const a = 0;
const obj = {
a: 1,
fn: function() {
console.log(this.a)
}
}
obj.fn(); // 1
const _fn = obj.fn;
_fn(); // 0 (浏览器控制台打印出来是undefined)
显示绑定(call/apply/bind)
call、apply直接调用函数并指定执行上下文
bind创建一个新函数并绑定传入的执行上下文返回
实现一个apply
Function.prototype.newApply = function(context = window) {
context.fn = this;
const result = arguments[1] ?
context.fn(arguments[1]) :
context.fn();
delete context.fn;
return result;
}
实现一个bind
Function.prototype.newBind = function() {
const context = this;
const args = Array.prototype.slice.call(arguments);
const newThis = args.shift();
return function() {
return context.apply(newThis, args)
}
}