用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

微客吧 首页 教程 微信小程序 新手教程 查看内容

微信小程序闭包问题引发的JS闭包解决方案

纸飞机 2018-3-8 09:34

作者:虫哥写代码,来自原文地址看到标题“闭包”很多人会觉得懵逼包括我在内,之前对闭包有所听闻但始终无法准确全面的了解。对于前端同学无论在面试还是在开发,都逃不过关于闭包的问题。最近项目中遇到变量访问权 ...

作者:虫哥写代码,来自

原文地址

看到标题“闭包”很多人会觉得懵逼包括我在内,之前对闭包有所听闻但始终无法准确全面的了解。对于前端同学无论在面试还是在开发,都逃不过关于闭包的问题。最近项目中遇到变量访问权限的问题一时间没考虑到闭包,郁闷了,在此感谢@Topqiang给我指点。本文阅读一遍不一定能够理解掌握,需要反复推敲和练习,有疑问欢迎随时在下方评论。


在网上搜索学习关于闭包的技术时发现讲的都比较抽象【我是菜鸟】,不好理解闭包的概念以及使用方法。今天我们带着疑问去学习:首先我给大家还原一下需求场景;对需求场景进行分析;引入闭包解决方案;升华闭包概念理解。废话少说直接步入正题。


还原需求场景


我要实现一个未知的多对多的数据请求并加载到页面中,由于后端接口限制,不支持多对多的同步返回,需要前端去做数据匹配处理。



下面来看看这种需求场景下,小程序前端代码是什么样子



按照常规双层for循环逻辑来理解是没有问题的,内层访问外层变量去遍历list


需求场景分析


这种需求下有同学会考虑后台将双层数据处理后返回给前端,但是如果后端考虑业务功能的解耦不做此操作,我们还是要解决这个问题。亲测单纯的双层for循环中内层访问外层变量是Ok的,加入wx.request过后内层将无法正常访问外层循环变量 i 。如果外层数据res.data的长度为3,那么i在外层for循环中正常遍历为:0、1、2;但是在内层for循环中遍历 i 的数据为:3、3、3,这个时候我对showdata.data赋值无法拿到完整的数据,而只能拿到最后一遍遍历出的数据。



分析到这里我们的目的就明确了,要想在内层wx.request中的for循环中得到外层变量 i ,怎么实现呢?


闭包解决方案


JS闭包可以很轻松的解决内层访问外层存活的私有变量。下面给出3种解决方案,仅供参考。

方案一:增加若干个对应的闭包域空间(这里采用的是匿名函数),专门用来存储原先需要引用的内容(下标),不过只限于基本类型(基本类型值传递,对象类型引用传递)



方案二:增加若干个对应的闭包域空间用来存储下标,将事件绑定在新增的匿名函数返回的函数上



方案三:使用ES6新语法 let 关键字:块作用域,不能重复声明覆盖,限制了变量的作用域,保证变量不会去污染全局变量



网上针对javascript解决闭包的方案还有很多,有兴趣的朋友可以深入了解。看了这么多内容不知道大家是否对微信小程序闭包有所了解。网上针对微信小程序闭包代码搜索最多的是下图:



升华闭包概念


闭包到底是什么?


官方的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分,闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

了解JS闭包之前我们回忆一下变量的作用域。javascript特殊的作用域函数内部变量访问全局变量,函数外部无法获取函数内的局部变量。函数内部声明变量要用var,不用var则声明全局变量。

Javascript语言的“链式作用域”结构(chain scope)导致子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的。闭包也就是将函数内部和函数外部连接起来的中介。


作用和应用场景


闭包可以读取函数内部的变量,也可以让这些变量的值始终保持在内存中。

在内存中维持一个变量。

通过保护变量的安全实现JS私有属性和私有方法(不能被外部访问)私有属性和方法在Constructor外是无法被访问的【本文涉及的场景】


闭包的注意点


1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

鲜花
鲜花
握手
握手
雷人
雷人
路过
路过
鸡蛋
鸡蛋
分享至 : QQ空间
收藏