JS基础之函数调用的困惑

前言

习惯了写java代码,然后开始学习js的时候,一开始总是会被js函数调用搞得有点晕乎,觉得有必要搞清楚js中函数调用不同的写法的一些含义和区别

js中的函数

要搞清楚js中函数调用为什么会这样,首先需要明白js中的一个概念,那就是:函数是JavaScript中的「一等公民」(Function is first-class citizen)
当你能够传递,返回和分配某个类型的时,那这个类型就被称为”一等公民”,js中的函数恰好就满足这些条件,所以js中的函数被称为是”一等公民”。
好了,不管js中函数是几等公民了,直接上代码来解决疑惑吧,假设我们页面中有一个按钮,点击的时候调用函数打印Hello World,函数代码如下:

1
2
3
function hello(){
document.write('Hello World');
}

看起来这段代码规规矩矩,没有什么问题,然后我们希望在一个组件被按压的时候调用这个函数,通常习惯了Java中函数调用的,可能顺手就是:onPress = hello();这对于习惯了java的人来说,可能觉得再普通不过了,但是对于js来说是有问题的。

如果我们希望组件在按压的时候输出这句话,很显然上面的调用方式是做不到的,因为上面这种写法,会在组件被渲染或者被加载的时候就会调用hello这个方法从而输出Hello World,也就是说如果带括号就表示该函数会被立即调用执行,并将返回值赋给onPress,而且当你再按压组件的时候也并不会再继续调用了(你可以试试),这显然并不是你想要的结果,那么如何达到想要的结果呢?有两种办法:

第一种

1
onPress = hello

这看起来是将函数赋值给onPress啊,是的,确切地说js中函数也是对象,这里就是将改函数对象的引用或者说是入口地址赋值给onPress,然后在我们按压组件触发onPress动作的时候,就会真正地调用hello函数,打印出Hello World

第二种

1
2
3
4
5
var hi = funtion hello(){
document.write('Hello World');
}
onPress = hi;
通过hi();这种也是相当于直接调用hello函数

这样看起来可能更直观一些,也就是先将函数赋值给一个变量,然后把该变量(指向函数的一个引用变量)赋值给onPress函数,因为onPress也是一个普通的函数,可以给它赋一个值,也可以给它赋一个函数,所以如果直接是第一种做法的话,就相当于把hello函数的返回值(虽然这里并没有显式的返回值)赋值给onPress了,自然达不到你想要按压组件调用函数输出Hello World的效果了。

再延伸一点就到ES6引进的箭头函数了(这里就不多说了):

1
2
3
4
hi = () => {
document.write('Hello World');
}
onPress = hi;

js还真是风骚啊。。。