函数声明中的回调实现有什么意义?

时间:2019-06-29 15:39:53

标签: javascript callback

在雄辩的Javascript书中,chapter 6中有以下示例:

class Matrix {
  constructor(width, height, element = (x, y) => undefined) {
    this.width = width;
    this.height = height;
    this.content = [];

    for (let y = 0; y < height; y++) {
      for (let x = 0; x < width; x++) {
        this.content[y * width + x] = element(x, y);
      }
    }
  }

 //...
}

如您所见,构造函数的第三个参数不仅是回调参数,而且实际上是回调的实现。

起初我以为,也许已实现的回调函数的主体被忽略了,但是至少将来构造函数中使用的回调将被检查为具有相同的签名。但是,我发现签名并不重要,因为下面的代码可以工作:

const test = new Matrix(2, 4, () => console.log('hello'));

那么实现回调(作为函数的参数)有什么意义呢?只是供读者推断将有多少参数传递给回调?

4 个答案:

答案 0 :(得分:2)

如果您未指定第三个参数,则 element 的默认值为(x, y) => undefined

请参阅此MDN link。它将提供一些见解。希望这会有所帮助。

答案 1 :(得分:1)

该示例对element进行的操作是设置默认值。在这种情况下,默认值不执行任何操作。

请注意,您也可以将()=>{}用作元素的默认值,它将在JavaScript中工作,因为在调用函数时该语言不会验证参数数(但是它可能会导致类型检查错误)在TypeScript中)。

这是一种常见的模式:您不用使用undefinednull,而是放置了一个不执行任何操作的默认参数,因此在代码中无需检查element在调用函数之前定义。参见:https://en.wikipedia.org/wiki/Null_object_pattern

诸如lodash之类的某些库还包含诸如noop之类的常量,它们被定义为空函数,因此您可以将代码编写为:

const noop = ()=>{}

class Matrix {
  constructor(width, height, element = noop) {
//...  
  }
}

其他信息:

Matrix构造函数似乎正在初始化一个维度Array以存储矩阵。您可以将嵌套的for循环替换为Array.from。像这样:

this.contents = Array.from(
  {length: height * width},
  n => element(n % width, Math.floor(n/height))
);

我没有检查数学,因此该示例可能存在索引错误。参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

答案 2 :(得分:0)

据我了解,它只是一个可选的初始化程序。如果使用() = > 0之类的名称进行调用,它将使用0而非undefined初始化矩阵。 (x,y) => x === y ? 1 : 0将产生一个单位矩阵。等等...。

(阅读本章后进行更新) 这是由书中的示例后面的句子所证实的:

  

构造函数具有一个宽度,一个高度和一个可选的元素函数,这些函数将用于填充初始值。

答案 3 :(得分:0)

此类具有3个适用于“构造器”的参数。

第三个是名为“ element”的回调函数,它是可选的,其默认值为“(x,y)=> undefined”。因此,如果在构建“ Matrix”类的新实例时未传递第三个参数,它将作为默认值。

如果您在此处传递特定功能(例如)

let myMatrix = new Matrix(100,100,(x,y) => x * y);

现阶段

this.content[y * width + x] = element(x, y);

它将相应的值返回到新“ Matrix”实例的“ this.content”属性的相应数组插槽。

因此您的矩阵将具有这样的“内容”属性(例如):

myMatrix.content[0] = 0;
myMatrix.content[1] = 0;
...
myMatrix.content[101] = 1;
myMatrix.content[102] = 2;
// and so on

否则,如果在创建新实例时不传递任何功能,则由于默认属性值为

,将为所有生成的“ this.content”属性的数组插槽分配未定义的值
  

(x,y)=>未定义