习题

向量类型

编写一个构造器Vec,在二维空间中表示数组。该函数接受两个数字参数xy,并将其保存到对象的同名属性中。

Vec原型添加两个方法:plusminus,它们接受另一个向量作为参数,分别返回两个向量(一个是this,另一个是参数)的和向量与差向量。

向原型添加一个getter属性length,用于计算向量长度,即点(x,y)与原点(0,0)之间的距离。

  1. // Your code here.
  2. console.log(new Vec(1, 2).plus(new Vec(2, 3)));
  3. // → Vec{x: 3, y: 5}
  4. console.log(new Vec(1, 2).minus(new Vec(2, 3)));
  5. // → Vec{x: -1, y: -1}
  6. console.log(new Vec(3, 4).length);
  7. // → 5

分组

标准的 JavaScript 环境提供了另一个名为Set的数据结构。 像Map的实例一样,集合包含一组值。 与Map不同,它不会将其他值与这些值相关联 - 它只会跟踪哪些值是该集合的一部分。 一个值只能是一个集合的一部分 - 再次添加它没有任何作用。

写一个名为Group的类(因为Set已被占用)。 像Set一样,它具有adddeletehas方法。 它的构造器创建一个空的分组,add给分组添加一个值(但仅当它不是成员时),delete从组中删除它的参数(如果它是成员),has 返回一个布尔值,表明其参数是否为分组的成员。

使用===运算符或类似于indexOf的东西来确定两个值是否相同。

为该类提供一个静态的from方法,该方法接受一个可迭代的对象作为参数,并创建一个分组,包含遍历它产生的所有值。

  1. // Your code here.
  2. class Group {
  3. // Your code here.
  4. }
  5. let group = Group.from([10, 20]);
  6. console.log(group.has(10));
  7. // → true
  8. console.log(group.has(30));
  9. // → false
  10. group.add(10);
  11. group.delete(10);
  12. console.log(group.has(10));
  13. // → false

可迭代分组

使上一个练习中的Group类可迭代。 如果你不清楚接口的确切形式,请参阅本章前面迭代器接口的章节。

如果你使用数组来表示分组的成员,则不要仅仅通过调用数组中的Symbol.iterator方法来返回迭代器。 这会起作用,但它会破坏这个练习的目的。

如果分组被修改时,你的迭代器在迭代过程中出现奇怪的行为,那也没问题。

  1. // Your code here (and the code from the previous exercise)
  2. for (let value of Group.from(["a", "b", "c"])) {
  3. console.log(value);
  4. }
  5. // → a
  6. // → b
  7. // → c