JS 闭包 实现原理 使用闭包的意义

好文链接
MDN 闭包
参考视频

  • 静态作用域 又叫 词法作用域(Lexcical Scope): 在编译时就确定了作用域范围;
  • 动态作用域:变量引用跟变量声明不是在编译时就绑定死了的。在运行时,它是在运行环境中动态地找一个相同名称的变量。

js 属于函数式编程。

闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这种组合就是闭包
闭包让你可以在一个内层函数中访问到其外层函数的作用域
在这里插入图片描述

只要函数能作为值传来传去(高阶函数),就一定会产生作用域不匹配的情况,这样的内在矛盾是语言设计时就决定了的。
可以认为闭包是为了让函数能够在这种情况下继续运行所提供的一个方案。
正因为这些数据只能被闭包函数访问,所以也就具备了对信息进行封装、隐藏内部细节的特性

简单计数器案例

let add = function() {
    let counter = 0
    return () => counter++
}
add() // 1
add() // 2
add = null // 手动释放闭包

本方法既实现了任何地方都能访问 counter,但又只能通过 add
全局变量能够通过闭包实现局部(私有)。

拥有相同名称的全局变量和闭包中的局部变量是不同的变量
全局变量,任何代码都可以更改全局变量,而无需调用函数

闭包意义

JavaScript 模块化之前,可以利用闭包实现封装,实现类似私有变量的效果。

闭包使得可以全局访问 函数的私有变量 但只有提供的接口可以访问 避免了污染全局变量。
私有变量受匿名函数的作用域保护,处理不好会造成内存泄漏

闭包可用于封装一段代码

fengzhuang = (function() {
	let a,b = 10,20;
	function sub() {
		return a + b;
	}
	function add() {
		return a - b;
	}
	return {
		add,
		sub
	}
})()

通过闭包参数i被保留下来

// 可以一次打印i
for (var i = 0; i < 4; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i)
        }, 0)
    })(i)
}

循环绑定事件

var a = document.getElementsByTagName("a");
for(var i =0; i<a.length; i++){ 
   a[i].onclick = (function(i){
        return function(){alert(i);}
   })(i);
}

闭包和对象在底层上是存在相似性的
构造函数中避免使用闭包,应通过原型中注册方法的方式

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值