• object和 Map的比较:一般地,objects会被用于将字符串类型映射到数值。object允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而 Map具有更多的优势。

    object的键均为 Strings类型,在 Map里键可以是任意类型。
    必须手动计算object的尺寸,但是可以很容易地获取使用 Map的尺寸。
    Map的遍历遵循元素的插入顺序。
    object有原型,所以映射中有一些缺省的键。(可以理解 为map=object,create(null)。

    这三条提示可以帮你决定用 Map还是object:
    (1)如果键在运行时才能知道,或者所有的键类型相同,所有的值类型相同,那就使用 map。
    (2)如果需要将原始值存储为键,则使用Map,因为object将每个键视为字符串,不管它是一个数字值、布尔值还是任何其他原始值。
    (3)如果需要对个别元素进行操作,使用object。
    WeakMap。WeakMap对象也是键值对的集合。它的键必须是对象类型,值可以是任意类型。它的键被弱保持,也就是说,当其键所指对象没有其他地方引用的时候,它会被GC回收掉。提供的接口 WeakMap与 Map相同。
    Map对象不同的是,WeakMap的键是不可枚举的。不提供列出其键的方法。列表是否存在取决于垃圾回收器的状态,是不可预知的。
    可以在”Why _Weak_Map?” WeakMap查看更多信息和示例。
    WeakMap对象的一个用例是存储一个对象的私有数据或隐藏实施细节。对象内部的私有数据和方法被存储在 WeakMap类型的 Privates的变量中。所有暴露出的原型和情况都是公开的,而其他内容都是外界不可访问的,因为模块并未导出 Privates对象。

    1. const privates = new WeakMap();
    2. function Public() {
    3. const me = {
    4. // Private data goes here
    5. };
    6. privates.set(this, me);
    7. }
    8. Public.prototype.method = function () {
    9. const me = privates.get(this);
    10. // Do stuff with private data in `me`...
    11. };
    12. module.exports = Public;
    • Array和 Set的对比:(1)一般情况下,在JavaScript中使用数组来存储一组元素,而新的集合对象有这些优势:

    (2)数组中用于判断元素是否存在的 Indexof函数效率低下。
    (3)Set对象允许根据值删除元素,而数组中必须使用基于下标的 Splice 方法。
    (4)数组的 Indexof方法无法找到 NaN值。
    (5)Set对象存储不重复的值,所以不需要手动处理包含重复值的情况。

    • Weakset与 set对象的主要区别有:

    (1)Weakset中的值必须是对象类型,不可以是别的类型
    (2)Weakset的“weak”指的是,对集合中的对象,如果不存在其他引用,那么该对象将可被垃圾回收。于是不存在一个当前可用对象组成的列表,所以Weakset不可枚举
    (3)Weakset的用例很有限,比如使用DOM元素作为键来追踪它们而不必担心内存泄漏。

    • Map的键和Set的值的等值判断

    (1)Map的键和 set的值的等值判断都基于same-value-zero algorithm
    (2)判断使用与===相似的规则。
    (3)-0和+0相等。
    (4)NaN与自身相等(与===有所不同)。

    • 一个 getter 是一个获取某个特定属性的值的方法。一个 setter 是一个设定某个属性的值的方法。你可以为预定义的或用户定义的对象定义 getter 和 setter 以支持新增的属性。定义 getter 和 setter 的语法采用对象字面量语法。下面例子描述了getters 和 setters 是如何为用户定义的对象o工作的。
      1. var o = {
      2. a: 7,
      3. get b() {
      4. return this.a + 1;
      5. },
      6. set c(x) {
      7. this.a = x / 2
      8. }
      9. };
      10. console.log(o.a); // 7
      11. console.log(o.b); // 8
      12. o.c = 50;
      13. console.log(o.a); // 25

    o对象的属性如下:
    o.a— 数字
    o.b— 返回 o.a + 1 的 getter
    o,c— 由 o.c的值所设置的o.a值的setter
    请注意在一个对象字面量语法中定义getter和setter使用”[gs]et property()”的方式(相比较于define[GS]etter)时,并不是获取和设置某个属性自身,容易让人误以为是”[gs]et propertyName(){ }”这样错误的使用方法。定义一个getter或setter函数使用语法”[gs]et property()”,定义一个已经声明的函数作为的getter和setter方法,使用object.defineProperty(或者 object.prototype.defineGetter 旧语法回退)
    下面这个例子展示使用getter和setter方法扩展 Date原型,为预定义好的Date类添加一个year的属性。定义属性year的getter和setter方法用到了Date类中已存在的getFullYear和setFullYear方法。
    定义属性year的getter和setter:

    1. var d = Date.prototype;
    2. Object.defineProperty(d, "year", {
    3. get: function() { return this.getFullYear() },
    4. set: function(y) { this.setFullYear(y) }
    5. });

    通过一个Date对象使用getter和setter:

    1. var now = new Date();
    2. console.log(now.year); // 2000
    3. now.year = 2001; // 987617605170
    4. console.log(now);
    5. // Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001

    原则上,getter 和 setter 既可以:

    当使用 使用对象初始化器 的方式定义getter和setter时,只需要在getter方法前加get,在setter方法前加set,当然,getter方法必须是无参数的,setter方法只接受一个参数(设置为新值),例如:

    1. var o = {
    2. a: 7,
    3. get b() { return this.a + 1; },
    4. set c(x) { this.a = x / 2; }
    5. };

    使用object.defineProperties的方法,同样也可以对一个已创建的对象在任何时候为其添加getter或setter方法。这个方法的第一个参数是你想定义getter或setter方法的对象,第二个参数是一个对象,这个对象的属性名用作getter或setter的名字,属性名对应的属性值用作定义getter或setter方法的函数,下面是一个例子定义了和前面例子一样的getter和setter方法:

    1. var o = { a:0 }
    2. Object.defineProperties(o, {
    3. "b": { get: function () { return this.a + 1; } },
    4. "c": { set: function (x) { this.a = x / 2; } }
    5. });
    6. o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
    7. console.log(o.b) // Runs the getter, which yields a + 1 or 6

    这两种定义方式的选择取决于你的编程风格和手头的工作量。当你定义一个原型准备进行初始化时,可以选择第一种方式,这种方式更简洁和自然。但是,当你需要添加getter和setter方法 —— 因为并没有编写原型或者特定的对象 ——使用第二种方式更好。第二种方式可能更能表现JavaScript语法的动态特性——但也会使代码变得难以阅读和理解。

    • 注意: “===” 运算符用来检查数值是否相等: 1 === “1” // return false and 1 == “1” // return true