JS函数调用(4种方法)

JavaScript 提供了 4 种函数调用:一般形式的函数调用、作为对象的方法调用、使用 call 和 apply 动态调用、使用 new 间接调用。

一般形式的函数调用

在默认状态下,函数是不会被执行的。使用小括号()可以激活并执行函数。在小括号中可以包含零个或多个参数,参数之间通过逗号进行分隔。

示例1

在下面示例中,使用小括号调用函数,然后直接把返回值传入函数,进行第二次运算,这样可以节省两个临时变量。

  1. function f(x,y) { //定义函数
  2. return x * y; //返回值
  3. }
  4. console.log(f(f(5,6), f(7,8))); //返回1680。重复调用函数

示例2

如果函数返回值为一个函数,则在函数调用时可以使用多个小括号反复调用。

  1. function f(x,y) { //定义函数
  2. return function () { //返回函数类型的数据
  3. return x * y;
  4. }
  5. }
  6. console.log(f(7,8) ()); //返回56,反复调用函数

示例3

设计递归调用函数,即在函数内调用自身,这样可以反复调用,但最终返回的都是函数自身。

  1. function f() { //定义函数
  2. return f; //返回函数自身
  3. }
  4. console.log(f() () () () () () () () () () () ()); //返回函数自身

当然,上述设计方法在实际开发中没有任何应用价值,不建议使用。

作为对象的方法调用

当一个函数被设置为对象的属性值时,称之为方法。使用点语法可以调用一个方法。

示例

下面示例创建一个 obj 对象,它有一个 value 属性和一个 increment 属性。increment 方法接收一个可选参数,如果该参数不是数字,那么默认使用数字 1。

  1. var obj = {
  2. value : 0,
  3. increment : function (inc) {
  4. this.value += typeof inc === 'number' ? inc :1;
  5. }
  6. }
  7. obj.increment();
  8. console.log(obj.value); //1
  9. obj.increment(2);
  10. console.log(obj.value); //2

使用点语法可以调用对象 obj 的方法 increment,然后通过 increment 方法改写 value 属性的值。在 increment 方法中可以使用 this 访问 obj 对象,然后使用 obj.value 方式读写 value 属性值。

使用 call 和 apply 动态调用

call 和 apply 是 Function 的原型方法,它们能够将特定函数当做一个方法绑定到指定对象上,并进行调用。具体用法如下:

function.call(thisobj, args...)
function.apply(thisobj, [args])

function 表示要调用的函数;参数 thisobj 表示绑定对象,即 this 指代的对象;参数 args 表示要传递给被调用函数的参数。call 方法可以接收多个参数列表,而 apply 只能接收一个数组或者伪类数组,数组元素将作为参数列表传递给被调用的函数。

示例1

下面示例使用 call 动态调用函数 f,并传入参数值 3 和 4,返回运算值。

  1. function f(x,y) { //定义求和函数
  2. return x + y;
  3. }
  4. console.log(f.call (null, 3, 4)); //返回7

在上面示例中,f 是一个简单的求和函数,通过 call 方法把函数 f 绑定到空对象 null 身上,以实现动态调用函数 f,同时把参数 3 和 4 传递给函数 f,返回值为 7。实际上,f.call(null,3,4) 等价于 null.m(3,4)。

示例2

上面示例使用 call 调用,实际上也可以使用 apply 方法来调用函数 f。

  1. function f(x,y) { //定义求和函数
  2. return x + y;
  3. }
  4. console.log(f.apply(null, [3,4])); //返回7

如果把一个数组或伪类数组的所有元素作为参数进行传递,使用 apply 方法就非常便利。

示例3

下面使用 apply 方法设计一个求最大值得函数。

  1. function max() { //求最大值函数
  2. var m = Number.NEGATIVE_INFINITY; //声明一个负无穷大的数值
  3. for (var i = 0; i < arguments.length; i ++) { //遍历所有实参
  4. if (arguments[i] > m) //如果实参值大于变量m
  5. m = arguments[i]; //则把该实参值赋值给m
  6. }
  7. return m; //返回最大值
  8. }
  9. var a = [23,45,2,46,62,45,56,63]; //声明并初始化数组
  10. var m = max.apply(Object, a); //动态调用max,绑定为Object的方法
  11. console.log(m); //返回63

在上面示例中,设计定义一个函数 max(),用来计算所有参数中的最大值参数。首先通过 apply 方法动态调用 max() 函数,然后把它绑定为 Object 对象的一个方法,并把包含多个值的数组传递给它,最后返回经过 max() 计算后的最大数组元素。

如果使用 call 方法,就需要把数组所有元素全部读取出来,再逐一传递给 call 方法,显然这种做法不是很方便。

示例4

也可以动态调用 Math 的 max() 方法来计算数组的最大值元素。

  1. var a = [23,45,2,46,62,45,56,63]; //定义并初始化数组
  2. var m = Math.max.apply(Object, a); //调用系统函数max
  3. console.log(m); //返回63

示例5

使用 call 和 apply 方法可以把一个函数转换为指定对象的方法,并在这个对象上调用该方法。当函数动态调用之后,这个对象的临时方法也就不存在了。

  1. function f() {
  2. return "函数f";
  3. }
  4. var obj = {};
  5. f.call(obj); //把函数f绑定为obj对象的方法
  6. console.log(obj.f()); //再次调用该方法,则返回编译错误


call 和 apply 方法的主要功能如下:

  • 调用函数。
  • 修改函数体内的 this 指代对象。
  • 为对象绑定方法。
  • 跨越限制调用不同类型的方法。


本小节主要介绍了如何使用 call 和 apply 方法调用函数,由于涉及类型、对象和 this 知识,后续我们还会继续深入讲解。

new 命令间接调用

使用 new 命令可以实例化对象,这是它的主要功能,但是在创建对象的过程中会激活并运行函数。因此,使用 new 命令可以间接调用函数。

示例

下面示例简单演示了如何用 new 命令,把传入的参数值显示在控制台。

  1. function (x,y) { //定义函数
  2. console.log("x =" + x + ", y =" + y);
  3. }
  4. new f(3,4);

使用 new 命令调用函数时,返回的是对象,而不是 return 的返回值。如果不需要返回值,或者 return 的返回值是对象,则可以选用 new 间接调用函数。

上一篇:NGINX 内存池有感


下一篇:某道笔试——多益