今日有入坑不久的小伙伴表示对闭包中return还不是很理解,这里用个简单的例子说明,先看下面的代码:
// html代码
<input type="text" id="name" >
// js代码
var input = document.querySelector('#name');
input.addEventListener('input', function () {
console.log(this.value)
})
这里没有任何难理解的地方,就是监听input的输入事件,实时输出input的值。
回调函数里的逻辑如果太多,需要抽离,这时候,得把匿名回调函数抽离成一个具体的函数print,如下:
function print(){
console.log(this.value)
}
input.addEventListener('input', print);
也没问题,一切正常,但是如果要往print函数里传值呢,比如就传一个简单的字符串“test”并输出这个值,这个也简单,可能就有以下写法:
function print(str) {
console.log(this.value, str)
}
input.addEventListener('input', print('test'));
此时会发现,一刷新页面,会立刻打印“undefined ‘test’”,而且在输入框里输入内容的时候,不会再继续打印,监听事件已经失效,跟想象的大不一样。
原因很简单
input.addEventListener('input', print)
这里的“print“”就是下面这个函数
function print(){
console.log(this.value)
}
这种写法是等价
input.addEventListener('input', function () {
console.log(this.value)
})
的,只是把回调函数抽出去了而已。
但是input.addEventListener('input', print('test'))
这种写法,意味着在绑定监听的时候就执行了一次print函数,而print函数里并没有写return,所以它是没有返回值的,非得要接收它的返回值,只能接收到undefined,函数名后有没有加括号在这里区别很大。
所以,以上代码可解释为:
- 页面初始化的时候执行一次print函数;
- 此时print函数跟输入框没关系,this指向window,打印this.value,获取不到值,输出undefined;
- 传入的参数’test’无影响,照原样输出;
- print函数无返回值,所以回调函数的位置处接收到的是undefined,后续输入框再输入内容的时候,已经没有回调函数,便不会有任何响应。
既然是因为没有返回值引起的,那就返回一个函数,使返回的函数占据原来回调函数的位置,就可解决这个问题:
function print(str) {
return function () {
console.log(this.value, str)
}
}
input.addEventListener('input', print('test'))
经验证,一切正常,这就是return的作用(时间有限,后边再继续更新闭包return的函数里的this改造)。