闭包
闭包是作用域使用的特殊情况,
我们把函数执行形成私有上下文,来保护和保存私有变量机制称为闭包。
1、是一个函数,2、可以访问其他作用域中的变量;
有两种表现
返回一个函数
function create () {let a = 200;return function () {console.log(a); // 200}}let a = 100let fn = create();fn();
作为参数被传递 ```javascript function create(fn) { let a = 100; fn(); }
let a = 200; function fn() { console.log(a); // 200,不是100 } create(fn)
可以看到,**(所有)自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方**<a name="OMg70"></a>## 应用1. 模仿块级作用域2. 保护外部函数的变量 能够访问函数定义时所在的词法作用域(阻止其被回收)3. 封装私有化变量4. 创建模块<a name="cGCDh"></a>### 隐藏数据```javascriptlet createCache = function () {let data = {};return {get: function (key) {return data[key];},set: function (key, value) {data[key] = value;return data;}}}let cache = createCache();cache.set('token', 'token');cache.get('token');
节流和防抖的使用
- 节流
以一个固定的间隔去触发,用于稀疏函数的执行频率
// 节流let throttle = function (fn, delay) {let prev = 0;return function () {let self = this;let argus = arguments;let now = Date.now();if (now - prev > delay) {fn.apply(self, argus);prev = now;}}}
- 防抖
频繁触发,只执行最后一次
// 防抖let debounce = function (fn, delay) {let timeout = null;return function () {let self = this;let argus = arguments;if (timeout) clearTimeout(timeout);timeout = setTimeout(function () {fn.apply(self, argus);}, delay);}}
实现bind函数
// 模拟bind的实现Function.prototype.bind1 = function () {// 将参数拆解为数组const args = Array.prototype.slice.call(arguments);// 获取this,并从数组剔除const _this = args.shift();// 原来的fn,fn.bind(...)的fn1const self = this;// 返回一个函数return function () {return self.apply(_this, args);}};function fn () {console.log(this);console.log(arguments);return 'this is a fn';}let fn1 = fn.bind1({name: 'fn',}, 10, 20);fn1();
缺点
变量会常驻内存,可能造成内存泄露
因为内存得不到及时的释放,可以人为的去置为null
js垃圾回收机制
- �标记使用法
当这个函数结束,变量不再使用就得到了释放;
- 引用计数法
在一定时间内不再使用;
