JavaScript 使用记录

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
    }
}

上面示例的输出结果:

js_functions_output_result_show

如上的示例代码中:代码 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
  1. 函数与一般变量的差异,在于如何使用数据。与函数相关的数据(或代码)可被执行。想执行函数时,就在函数名称后加上括号 (),如果函数需要变量,也要记得附加上。
  2. 函数变量的值不是代码本身,而是指向存储代码的存储器位置的引用。

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()
    }

上面的测试代码的输出结果:

回调函数测试输出

实际上,结合 JavaScript 中的匿名函数 这篇,将对象的概念引入一起理解,会发现上面的那些不相等的情况,实际上是因为不同的对象进行比较,不相等是必然的。

上一篇 下一篇

猜你喜欢

热点阅读