分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

JS 闭包 p5

发布时间:2023-09-06 02:31责任编辑:沈小雨关键词:闭包

终于到闭包了,写了一晚上,好激动:

首先闭包,个人是这样理解的(比较好记):闭包是一种能力,是一种可以访问内部函数作用域的能力或者说是一种行使权力,一旦你拥有这个能力,你将可以访问内部函数的作用域。??还是有点晕,看例子:

function fn(){ ??var a = 2; ??function x(){ ??????console.log(a); ??} ????return x;}var b = fn();b();//2

最终结果输出2,fn 函数内部声明了一个x函数,x函数内部访问作用域中的a,之前提到过,a与x函数是fn函数的内部声明,外部是无法访问的,比如直接 x()或者a是会报错的,但是如果我们把x函数当作函数返回给全局作用域中声明的b,

那么b得到了内部函数x的引用,从而获取了可以访问内部声明变量a的能力,或者说涵盖fn内部作用域的使用权利,这种能力或者说叫使用权、访问权就是闭包。

明白没?

另外:因为闭包的存在,垃圾回收器不会回收,因为内部作用域还存在并且被x使用。

再看下面的(书中的例子,拿来):

function fn(){ ??var a = 2; ??function foo(){ ?????console.log(a); ??}; ????out(foo);} ???function out(f){ ??f(); ??}

fn(); // 2

首先定义了fn函数,然后在其内部定义了一个foo内部函数,最后在fn结尾调用外部的out函数(这个大家都懂,调用外部的函数呗),然后外部函数out形参接收一个函数f(回调函数之前说的),

并调用和执行f(就是foo),奇怪不? 其实和上面的例子道理是一样的,foo这个内部函数拥有了fn内部作用域的闭包或者说能力,在out函数中使用了它,也就是我们说的闭包。所以能够访问fn的内部变量a,最终输出2。

注意的是:关键词是“内部函数”,无论通过何种手段将内部函数传递到所在的词法作用域之外,它都会持有对原始定义作用域的引用。而在执行这个内部函数的引用的时候就会使用到闭包,也就是能力。

或者说闭包是个角色或者是张三,张三看着器材室,你是张三的领导,你需要使用器材,把它叫来,说要篮球,它就给你了。张三就是闭包(不太准确希望你能明白)。

回调函数可以说是最典型的闭包使用者~~

再看一个:

// 到百度上试试var a = document.getElementById(‘wrapper‘);// 添加一个监听事件a.addEventListener(‘click‘,function(e){alert(1)});

是不是明白了?

再来一个:

function x(a){ ????setTimeout(function timer(){console.log(a)},1000) };x(1);// 1秒后// 输出1

setTimeout 作为全局作用域的一个函数(window的),timer作为内部函数拥有对x函数内部作用域的行使权,可以访问参数a,且一直持有,当实际调用时,timer行驶了这种权利,访问了a,拿到了篮球~ 这就是闭包。

最后一个,这个比较经典(写完回家):

for(var i = 1;i<=5;i++){ ?setTimeout(function timer(){console.log(i);},i*1000);}

最终会输出5次6~,这样也是,下面会一次输出5次6

for(var i = 1;i<=5;i++){ ?setTimeout(function timer(){console.log(i);},0);}

这个是之前在p3里说的吧好像,var i 会在全局作用域或者说外部作用域声明一个 i其实,等到跳出循环的时候 i = 6;

而这里的timer 实际上是拥有了对全局作用域的访问使用权~  而实际上这个i在循环的时候会不停的把这个i重新赋值,一直赋值,直接终止在6上,

虽然timer拥有对i的使用权,但是只会调用最终章,也就是确定后的值,也就是6(因为他们被封闭在一个共享的全局作用域中!

那么像实现上面咋整,可以这样:

// 因为立即执行函数IIFE 会创建一个内部作用域for(var i = 1;i<=5;i++){ ?(function(x){ ????setTimeout(function timer(){console.log(x);},0); ?})(i); ?}

最爽的是这样,用let(之前说了let会独立声明,不会影响外部,是不是最爽了,把var改成let,一劳永逸)

for(let i = 1;i<=5;i++){ ?setTimeout(function timer(){console.log(i);},0);}

好了,先写道着~  回家 - -

JS 闭包 p5

原文地址:https://www.cnblogs.com/jony-it/p/10332253.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved