轻源码

  • QingYuanMa.com
  • 全球最大的互联网技术和资源下载平台
搜索
一起源码网 门户 微信小程序 查看主题

点击编译为什么老是弹出设置框,for+i+function+function组合代码到底怎么理解 ... ...

发布者: ddzxf | 发布时间: 2018-1-5 17:26| 查看数: 2603| 评论数: 1|帖子模式

作者:苏雄伟,来自原文地址

一:点击编译为什么老是弹出设置框

在对微信小程序的代码进行了一些调整以后,希望编译运行起来看看,结果却老是弹出自定义预览,要咱们填写启动页面和页面自定义参数等,如下图

即使我们填写了,点击编译,也会弹出,为什么?

一开始我也不明白,老是点那个,后来我才发现,这个工具把咱们误导了,这里面有两个相关并不一样的功能,一个是编译运行,一个是编译设置,下面我们来说说它俩。 
编译运行是上面的那个图标,它的快捷键是ctrl+b,它的作用是编译修改过的代码并运行调试,也就是我们想要的编译运行功能,如下图所示:

编译设置是下面那个图标+编译文字(有点误导),它实际的作用就是编译设置,就是当程序启动时首先启动那个界面,并且设置传给那个界面的参数,如下图:

那么编译设置应该怎么设置呢?我给下实例图:

ctrl+b启动时打出的日志,如下:

page/component/index: onLoad have been invoked 
index.js [sm]:17 Object {name: "bright789", year:"2017"}

这个就是方便我们更好的调试,毕竟有的页面不在第一界面,但经过编译设置以后,在调试阶段就可以变成第一,调试完后又可以修改回来!

二:示例使用到了大量的for+i+function+function组合代码到底怎么理解

在微信小程序示例代码里面使用到了非常多的for+i+function+function这种组合代码,有时看了头晕,到底是什么意思?起什么作用或者说解决什么问题?它跟JavaScript的closure(闭包)有什么关联?今天我们就来学习一下它。 
下面使用一个作为例子:

  1. var toastNum = 3
  2. var pageData ={}
  3. pageData.data ={}
  4. for(var i =0; i <= toastNum; ++i) {
  5. pageData.data['toast'+i+'Hidden'] = true;
  6. (function (index) {
  7. pageData['toast'+index+'Change'] = function(e) {
  8. var obj = {}
  9. obj['toast'+index+'Hidden'] = true;
  10. this.setData(obj)
  11. }
  12. pageData['toast'+index+'Tap'] = function(e) {
  13. var obj = {}
  14. obj['toast'+index+'Hidden'] = false
  15. this.setData(obj)
  16. }
  17. })(i)
  18. }

Page(pageData) 
这段代码来自微信小程序示例代码: page/component/component-pages/wx-toast/wx-toast.js 
这段代码的代码的主要意思是通过一个for循环,把object对象pageData里的object变量data的toast0Hidden,toast1Hidden,toast2Hidden,toast3Hidden变量赋值都赋值成true,把object对象pageData里toast0Change,toast1Change,toast2Change,toast3Change变量分别赋值一个匿名回调函数,此回调函数如下:

  1. function(e) {
  2. var obj = {}
  3. obj['toast'+index+'Hidden'] = true;
  4. this.setData(obj)
  5. }

把object对象pageData里toast0 Tap,toast1 Tap,toast2C Tap,toast3Tap变量分别赋值一个匿名回调函数,此回调函数如下:

  1. function(e) {
  2. var obj = {}
  3. obj['toast'+index+'Hidden'] = false
  4. this.setData(obj)
  5. }

但是为什么for循环里面还有一个

  1. (function (index) {
  2. ……
  3. })(i)

这样的东西呢?是不是多此一举,让代码复杂化,能不能去掉,如果不是不能,哪又起什么作用呢?

为了理解这个东西,我们先学习一点点javascript的作用域的知识 
在javascript的世界里,只有全局作用域和函数作用域,没有块作用域,那么什么是全局作用域,什么又是函数作用域呢?全局作用域就是在全局范围都起作用的一些,其中囊括在函数之外定义的变量和函数内没有声明为var的变量,如果上面的toastNum,pageData,特别指出的是i它也是,而函数作用域就是在函数以内的作用范围,包括参(),函数体{}内,比如上面代码的var obj={}中的obj和函数参数index。 
为了看到效果,我们把去掉,调整代码如下:

  1. for(var i = 0; i<= toastNum; ++i) {
  2. pageData.data['toast'+i+'Hidden'] = true;
  3. pageData['toast'+i+'Change']= function(e) {
  4. var obj = {}
  5. obj['toast'+i+'Hidden'] = true;
  6. this.setData(obj)
  7. }
  8. pageData['toast'+i+'Tap'] = function(e) {
  9. var obj = {}
  10. obj['toast'+i+'Hidden'] = false
  11. this.setData(obj)
  12. }
  13. }

调试时看变量初始化,好像都正常,该有的都有了

那咱们继续,点击界面上其中的某个按钮,调试结果:

调试的i,怎么变成4,进而形成toast4Hidden,从上上图我们知道,我们最高是3,怎么跑出4来了?哦,原来,i由于javascript里没有区块作用域,所以i现在全局作用域,并且只有一个i,当for循环完后i就变成了4,所以当回调函数使用它时就是4了,那么跟我们想的不一样,我们想的是当点击第一个btn时,就是相应的toast1Hidden,那怎么办?一种通用的就办法就引了函数作用域,就是javascript所说的closure(闭包),就是把i当参数传入一个函数,然后被传入的函数有一个参数是用来复制保存当时的i的,如下代码:

  1. (function (index) {
  2. ……
  3. })(i)

所以现在只有4个index变量(for循环以后),复制缓存i的四个状态:0,1,2,3,而这4个index的作用是函数作用域,在上面function(){}的{}里头有效,所以就可以实现我们之前想的目标,即函数里的index是对应的。 
最后代码我贴一下,大家自己去体会下之间的不同: 
Js文件代码:

  1. var toastNum = 3
  2. var pageData ={}
  3. pageData.data ={}
  4. for(var i = 0; i<= toastNum; ++i) {
  5. pageData.data['toast'+i+'Hidden'] = true;
  6. (function (index) {
  7. pageData['toast'+index+'Change'] =function(e) {
  8. var obj = {}
  9. obj['toast'+index+'Hidden'] = true;
  10. this.setData(obj)
  11. }
  12. pageData['toast'+index+'Tap'] = function(e){
  13. var obj = {}
  14. obj['toast'+index+'Hidden'] = false
  15. this.setData(obj)
  16. }
  17. })(i)
  18. }
  19. Page(pageData)

Wxml文件代码:

  1. <viewclass="page">
  2. <view class="page__hd">
  3. <textclass="page__title">toast</text>
  4. <textclass="page__desc">toast提示</text>
  5. </view>
  6. <view class="page__bd">
  7. <view class="btn-area">
  8. <view class="body-view">
  9. <toasthidden="{{toast1Hidden}}" bindchange="toast1Change">
  10. 默认
  11. </toast>
  12. <button type="default"bindtap="toast1Tap">点击弹出默认toast</button>
  13. </view>
  14. <view class="body-view">
  15. <toasthidden="{{toast2Hidden}}" icon="warn"bindchange="toast2Change">
  16. 设置icon
  17. </toast>
  18. <button type="default" bindtap="toast2Tap">点击弹出设置icon的toast</button>
  19. </view>
  20. <view class="body-view">
  21. <toasthidden="{{toast3Hidden}}" duration="3000"bindchange="toast3Change">
  22. 设置duration
  23. </toast>
  24. <button type="default"bindtap="toast3Tap">点击弹出设置duration的toast</button>
  25. </view>
  26. </view>
  27. </view>
  28. </view>

最新评论

AK设计 发表于 2022-5-8 08:47
音频提取网站

浏览过的版块

轻源码让程序更轻更快

QingYuanMa.com

工作时间 周一至周六 8:00-17:30

侵权处理

客服QQ点击咨询

关注抖音号

定期抽VIP

Copyright © 2016-2021 https://www.171739.xyz/ 滇ICP备13200218号

快速回复 返回顶部 返回列表