JavaScript 函数式编程中的引用函数、调用函数和回调函数
2020-06-24 本文已影响0人
赵者也
JavaScript 函数式编程中的引用函数、调用函数和回调函数
阅读本文前先阅读《JavaScript 中的匿名函数》可以更好的理解本文。
1. 引用函数与调用函数的区别
引用函数与调用函数的差别与函数名称后是否带有括号 ()
有关。函数引用只会单独出现,但函数调用则必定后面带有括号,很多时候还附有参数。
举个例子(本示例是个 QML 示例,但是 JS 功能一致):
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Text {
id: output
anchors.centerIn: parent
}
function f1(){
var x = 5;
return x;
}
function f2() {
var x = 5;
return x;
}
function f3(){
var x = 5;
return function(){
return x;
}
}
Component.onCompleted: {
var result = ""
var a1 = f1;
var b1 = f1;
result += "a1====" + a1 + "\n"
result += "b1====" + b1 + "\n\n"
result += "a1 === b1 result=====> " + (a1 === b1) + "\n\n"
var a2 = f2();
var b2 = f2();
result += "a2====" + a2 + "\n"
result += "b2====" + b2 + "\n\n"
result += "a2 === b2 result=====> " + (a2 === b2) + "\n\n"
var a3 = f3();
var b3 = f3();
result += "a3====" + a3 + "\n"
result += "b3====" + b3 + "\n\n"
result += "a3 === b3 result=====> " + (a3 === b3) + "\n\n"
var a4 = function() {
x = 8;
return x;
}
var b4 = function() {
x = 8;
return x;
}
result += "a4====" + a4 + "\n"
result += "b4====" + b4 + "\n\n"
result += "a4 === b4 result=====> " + (a4 === b4) + "\n\n"
result += "a3()====" + a3() + "\n"
result += "b3()====" + b3() + "\n\n"
result += "a3() === b3() result=====> " + (a3() === b3()) + "\n"
output.text = result
}
}
上面示例的输出结果:
![](https://img.haomeiwen.com/i4011078/935ecd8bbb2bbd77.png)
如上的示例代码中:代码 a1b1 和代码 a2b2 分别是函数引用和函数调用的列子,返回都为true,代码 a3b3 是函数调用的列子,代码 a4b4 是函数引用的列子,返回都为 false。
我们现在来理解下函数引用和函数调用的本质区别:当引用函数时候,多个变量内存存储的是函数的相同的入口指针,因此对于同一个函数来讲,无论多少个变量引用,他们都是相等的,因为对于引用类型(对象,数组,函数等)都是比较的是内存地址,如果他们内存地址一样的话,说明是相同的;但是对于函数调用来讲,比如代码 a3b3,每次调用的时候,都被分配一个新的内存地址,所以他们的内存地址不相同,因此他们会返回 false,但是对于代码 a2b2 来讲,我们看到他们没有返回函数,只是返回数值,他们比较的不是内存地址,而是比较值,所以他们的值相等,因此他们也返回 true,我们也可以看看如下实列化一个对象的列子,他们也被分配到不同的内存地址,因此他们也是返回 false 的;如下代码测试:
function F(){
this.x = 5;
}
var a = new F();
var b = new F();
console.log(a === b); // false
- 函数与一般变量的差异,在于如何使用数据。与函数相关的数据(或代码)可被执行。想执行函数时,就在函数名称后加上括号
()
,如果函数需要变量,也要记得附加上。 - 函数变量的值不是代码本身,而是指向存储代码的存储器位置的引用。
2. 回调函数
简单理解就是:函数 a 有一个参数,这个参数是个函数 b,当函数 a 执行完以后执行函数 b。那么这个过程就叫回调。下面是一段 QML 测试代码:
function a(callback) {
console.log("我是parent函数a!");
console.log("调用回调函数");
callback();
}
function b(){
console.log("我是回调函数b");
}
function c(){
console.log("我是回调函数c");
}
function test() {
a(b);
a(c);
}
Component.onCompleted: {
test()
}
上面的测试代码的输出结果:
![](https://img.haomeiwen.com/i4011078/4ccd9c397d714a40.png)
实际上,结合 JavaScript 中的匿名函数 这篇,将对象的概念引入一起理解,会发现上面的那些不相等的情况,实际上是因为不同的对象进行比较,不相等是必然的。