最近在开发一个微信小程序,语言肯定是用JavaScript。JS之前就学习过了,但很久没用,有些东西都忘了。
现在再次使用,很多东西一下子又想起来了,索性趁着这个点把想法记下来。
一、JS里函数的基本知识
先来看《HeadFirst JavaScript Programming》一书里对JS函数的解释:
我翻译如下:
如果在JavaScript之前,你已经学过较为传统的编程语言,那么你可能会觉得函数……就只是函数而已。你可以声明函数,调用函数,除此之外函数就没什么用了。
现在,你知道了JavaScript里的函数也是值类型(value)——可以被赋值给变量。一旦是值这个类型了,这就意味着我们可以把函数这个值作为另一个函数的参数传递,作为返回值return,甚至存储在数组或者对象里,就如同我们操作numbers,bool,string,objects这些值一样。
计算机科学家把能进行这些操作的值称作:一阶值(First-Class Value)。我们可以对一阶值做如下操作:
- 赋值给变量(或者存在数组或对象里)
- 作为参数传递给函数
- 作为函数的返回值
因此有一阶值特性的函数就叫做一阶函数(First-Class Function)。这个特性可以说是现代编程语言的标配,JavaScript也不例外。
可以把函数存在对象里面:
可以把函数作为参数传递
二、开发中会依靠的知识:闭包
有了上面一阶值的特性,编程语言可以变得非常灵活,函数可以随意游走,在不同的领域(Domain)内穿梭。
在实际的开发中,比如微信小程序开发,通常都会有一个实际的需求——在不同的页面或者说类之间可以共享各自的值。比如在这个类里进行的逻辑操作,会在执行过程中使用到另一个类的里面的值。这时候就需要依靠闭包(Closure)了。
略过原理,直接说如何用。
首先把函数作为参数传递:
home.getBannerData((data) => { that.setData({ bannerArr: data, }); });复制代码
然后在getBannerData()里,早在定义的时候就把这个函数参数用在哪里给安排好了:
getBannerData(callback){ var that=this; var param={ url: 'banner/1', sCallback:function(data){ data=data.items; callback && callback(data); // 在这里执行这个参数函数 } }; this.request(param); }复制代码
值得注意的是,这里的参数函数是被放在对象的函数value里执行。参数函数callback所在的对象又被作为函数的参数传递了。这里就可以看出有一阶值特性的编程语言的灵活性。
最后param对象的sCallback这个key被调用,key对应的函数value被执行:
request(params, noRefetch) { var that = this, ...略... wx.request({ url: url, data: params.data, method: params.type, header: { ...略... }, success: function(res) { var code = res.statusCode.toString(); var startChar = code.charAt(0); if (startChar == '2') { params.sCallback && params.sCallback(res.data); // 被执行 } ...略...复制代码
被执行的函数会回到之前定义的地方执行函数体内的代码,即:
sCallback:function(data){ data=data.items; callback && callback(data); // 回到这执行 }复制代码
最关键的步骤来了,params.sCallback && params.sCallback(res.data);
,这个res.data是在这个领域(Domain)内的值,但是现在被回传给了上一个领域,也就是说定义这个函数的地方sCallback:function(data)
,这个data
参数现在的值则是上个领域的res.data
,这也就达成了领域之间的值共享。
然后执行callback && callback(data)
这句时,也是回到定义它的地方执行,同时也把res.data
这个值传了过去。
home.getBannerData((data) => { that.setData({ bannerArr: data, }); });复制代码
在回来执行这个函数体的时候,getBannerData((data)
里的data现在的值就是res.data
了,也就是在这个领域里也用到了这个值。最后再通过微信小程序的setData()
函数,把res.data
这个值赋给这个界面。
三、总结
通过函数的传递,然后执行函数时,又回到之前定义的地方,同时还可以顺带把不同领域(Domain)里原本不共通的值传递共享,这就是闭包,在JS里这样的函数也叫回调函数。
这样类之间可以传递数据。在前端开发中,直接达成的效果就是,在页面跳转时,不同页面间的数据可以传递共享了。