20200222

@xiaojingzhao

Plan

快看完了的《你不知道的 js》

Notes

  • 一个 obj 可以通过 Object.getOwnPropertyDescriptor 来拿到特定的属性描述符。"__proto__" 取出来是 undefined?
function Foo() {}
const foo = new Foo();
foo.hasOwnProperty(foo, "__proto__"); //false
Object.getOwnPropertyNames(foo); //[]
Object.getOwnPropertyDescriptor(foo, "__proto__"); //undefined
const a = {};
a.hasOwnProperty("__proto__"); //false
Object.getOwnPropertyDescriptor(a, "__proto__"); //undefined

a.__proto__.hasOwnProperty("__proto__"); // true
Object.getOwnPropertyDescriptor(a.__proto__, "__proto__"); // {enumerable: false, ....}

测试了一下,似乎只有 Object.prototype 才能取出 __proto__ 的描述符。而 __proto__ 在 Object.prototype 中是 getter 和 setter 方法。

回想到昨天的例子:a 相当于 Object.prototype -- b.__proto__ === a

a = { a: "a" };
Object.defineProperties(a, {
  a1: {
    value: "a1",
    writable: false
  },
  a2: {
    get() {
      return this.a;
    },
    set(val) {
      this.a = val;
    }
  }
});
b = Object.create(a);

测试一下 b 上的 a2。 和 foo 的例子表现一致。推测一下,首先能在 foo 中看到 __proto__ 是因为在 Object.prototype 中是一个 getter/sertter。foo 中看到 __proto__ 继承于 Object,并不是 ownProperty。这也解释了为什么在 foo 和 b 上无法获得 __proto__ 的描述符。

b.hasOwnProperty("a2"); // false
Object.getOwnPropertyDescriptor(b, "a2"); // undefined
a.hasOwnProperty("a2"); // true
Object.getOwnPropertyDescriptor(a, "a2"); // {enumerable: false ....}
  • Object.create 和 new 的区别。
function Foo() {}
const foo1 = new Foo();
foo1.__proto__ === Foo.prototype; // true

const foo2 = Object.create(Foo);
foo2.__proto__ === Foo; // true
foo2 instanceof Foo; //false

const foo3 = Object.create(Foo.prototype);
foo3 instanceof Foo; //true
  • Object.create 的 pollyfill -- 创建一个 obj,这个 obj 的 __proto__ 指向 baseObj
function ObjectCreate(baseObj) {
  function F() {}
  F.prototype = baseObj; // 利用 new F().__proto__ === F.prototype 的原理
  let obj = new F();
  return obj;
}

缺陷:无法为属性添加描述符。

More