Use apply to Call Functions with Different

Item 21: Use apply to Call Functions with Different
Numbers of Arguments
Imagine that someone provides us with a function that calculates the
average of any number of values:

average(1, 2, 3); // 2
average(1); // 1
average(3, 1, 4, 1, 5, 9, 2, 6, 5); // 4
average(2, 7, 1, 8, 2, 8, 1, 8); // 4.625

The average function is an example of what’s known as a variadic or
variable-arity function (the arity of a function is the number of argu-
ments it expects): It can take any number of arguments. By com-
parison, a fixed-arity version of average would probably take a single
argument containing an array of values:

1 averageOfArray([1, 2, 3]); // 2
2 averageOfArray([1]); // 1
3 averageOfArray([3, 1, 4, 1, 5, 9, 2, 6, 5]); // 4
4 averageOfArray([2, 7, 1, 8, 2, 8, 1, 8]); // 4.625

The variadic version is more concise and arguably more elegant. Vari-
adic functions have convenient syntax, at least when the caller knows
ahead of time exactly how many arguments to provide, as in the
examples above. But imagine that we have an array of values:

var scores = getAllScores();

How can we use the average function to compute their average?
average(/* ? */);
Fortunately, functions come with a built-in apply method, which is
similar to their call method, but designed just for this purpose. The
apply method takes an array of arguments and calls the function as
if each element of the array were an individual argument of the call.
In addition to the array of arguments, the apply method takes a first
argument that specifies the binding of this for the function being
called. Since the average function does not refer to this , we can sim-
ply pass it null :

var scores = getAllScores();
average.apply(null, scores);

If scores turns out to have, say, three elements, this will behave the
same as if we had written:

average(scores[0], scores[1], scores[2]);

The apply method can be used on variadic methods, too. For example,
a buffer object might contain a variadic append method for adding
entries to its internal state (see Item 22 to understand the implemen-
tation of append ):

var buffer = {  state: [],
  append: function() {
    for (var i = 0, n = arguments.length; i < n; i++) {
      this.state.push(arguments[i]);
    }
  }
};

The append method can be called with any number of arguments:

buffer.append("Hello, ");
buffer.append(firstName, " ", lastName, "!");
buffer.append(newline);

With the this argument of apply , we can also call append with a com-
puted array:

buffer.append.apply(buffer, getInputStrings());

Notice the importance of the buffer argument: If we passed a dif-
ferent object, the append method would attempt to modify the state
property of the wrong object.
Things to Remember
? Use the apply method to call variadic functions with a computed
array of arguments.
? Use the first argument of apply to provide a receiver for variadic
methods.

文章来源于:Effective+Javascript编写高质量JavaScript代码的68个有效方法 英文版

时间: 2025-01-08 05:17:05

Use apply to Call Functions with Different的相关文章

[Functional Programming] Running though a serial number prediction functions for tagging, pairing the result into object

Let's we have some prediction functions, for each prediction function has a corresponding tag: const {gt, lte, gte, lt} = require('ramda'); const {flip} = require('crocks'); const getSmlPred = and(flip(gt, -1), flip(lte, 50)); const getMedPred = and(

Spark学习笔记

Spark 阅读官方文档 Spark Quick Start Spark Programming Guide Spark SQL, DataFrames and Datasets Guide Cluster Mode Overview Spark Standalone Mode 重要的概念:resilient distributed dataset (RDD), a collection of elements partitioned across the nodes of the cluste

函数即对象 Scala (一)

Lecture 4.1 Functions as Objects 将匿名函数看成一个对象   A=>B 其实就是scala.Function1[A, B] Function1 是scala系统库的一个Trait,包含一个参数的函数特质 Expansion Function Values 通过 x => x*x 解释这个匿名函数其实也是一个匿名类 new class AnoFun extends Function1[Int, Int]{ apply(x: Int) =x*x } Expansio

ubuntu设置关闭屏幕和锁定

见链接:http://askubuntu.com/questions/177348/how-do-i-disable-the-screensaver-lock If you want to wrap your app in a script that takes care of this for you when you launch it (or GUI simply isn't an option), the best command-line solution as of Ubuntu 1

tensorflow源码学习之五 -- 同步训练和异步训练

同步和异步训练是由optimizer来决定的. 1. 同步训练 同步训练需要使用SyncReplicasOptimizer,参考https://www.tensorflow.org/api_docs/python/tf/train/SyncReplicasOptimizer .其他optimizer都属于异步训练方式. 同步训练实现在sync_replicas_optimizer.py文件中的def apply_gradient()方法中.假设有n个参数: 对于PS,需要创建n个参数收集器(每个

TypeScript 上手教程

无疑,对于大型项目来说,Vanilla Js 无法满足工程需求.早在 2016 年 Anuglar 在项目中引入 TypeScript 时,大概也是考虑到强类型约束对于大型工程的必要性,具体选型考虑可参考这篇文章.然后可以看到 TypeScript 在社区中逐渐升温.但凡社区中举足轻重的库,如果不是原生使用 TypeScript 编写,那么也是通过声明文件的方式对 TypeScript 提供支持,比如 React(虽然不是包含在官方仓库中,而是通过 @types/react),同时官方脚手架工具

Typescript VSCode编译

今天项目使用了Typescript来写了点代码,然后发现了可以使用VSCode时时的编译,记录下来! 一.安装ts 执行 npm i -g typescript二.node必须安装,自行搜索 三.先随便创建一个文件夹,里面弄一个index.ts的文件 三.在index.ts同级目录下执行 tsc --init执行之后会生成tsconfig.json的文件,内容大概这样子:(www.gendan5.com) {"compilerOptions": {/ Basic Options /&q

已有的react-native 项目配置TypeScript

来自:https://zhuanlan.zhihu.com/p/83291118 1.给RN项目添加 TypeScriptyarn add --dev typescript 或者 npm install typescript --save 2.给项目添加 react-native-typescript-transformer 库yarn add --dev react-native-typescript-transformer 3.初始化 TypeScript 配置文件yarn tsc --in

SWIG 3 中文手册——9. SWIG 库

目录 9 SWIG 库 9.1 %include 指令与库搜索路径 9.2 C 数组与指针 9.2.1 cpointer.i 9.2.2 carrays.i 9.2.3 cmalloc.i 9.2.4 cdata.i 9.3 C 字符串处理 9.3.1 默认字符串处理 9.3.2 传递二进制数据 9.3.3 使用 %newobject 释放内存 9.3.4 cstring.i 9.4 STL/C++ 库 9.4.1 std::string 9.4.2 std::vector 9.4.3 STL