• 你不知道的 JavaScript 系列上( 54) - 检查 [[Prototype]]


    instanceof

    function Foo() {
      // ...
    }
    Foo.prototype.blah = ...;
    var a = new Foo();

    我们如何找到 a 的 “祖先” (委托关联)呢?第一种方法:

    a instanceof Foo; // true
    instanceof 操作符的左操作符是一个普通的对象,右操作数是一个函数。 instanceof 回答的问题是:在 a 的整条 [[Prototype]] 链中是否有指向 Foo.prototype 的对象?可惜,这个方法只能处理对象和函数之间的关系。如果想判断两个对象之间是否通过 [[Prototype]] 链关联,只用 instanceof 无法实现。


    isPrototypeOf

    Foo.prototype.isPrototypeOf(a); // true

    isPrototypeOf 回答的问题是:在 a 的整条 [[Prototype]] 链中是否出现过 Foo.prototype

    这里我们只需要两个对象就可以判断它们之间的关系。举例来说:

    // 非常简单: b 是否出现在 c 的 [[Prototype]]链中?
    b.isPrototypeOf(c)

    这个方法并不需要使用函数,它直接使用 b 和 c 之间的对象引用来判断它们的关系。

    getPrototypeOf
    我们也可以直接获取一个对象的 [[Prototype]] 链。在 ES5 中,标准的方法是:
    Object.getPrototypeOf(a);
    Object.getPrototypeOf(a) === Foo.prototype; // true

    __proto__

    绝大多数浏览器也支持一种非标准的方法来访问内部 [[Prototype]] 属性:

    a.__proto__ === Foo.prototype; // true
    这个奇怪的 __proto__ 属性 “神奇地” 引用了内部的 [[Prototype]] 对象。这个和 .constructor 一样,实际上并不存在于正在使用的对象中,它和其他的常用函数(.toString(), .isPrototypeof(...)等等)一样,存在于内置的 Object.prototype中。它们是不可枚举的
    __proto__ 看起来很像一个属性,但是实际上它更像一个 getter/setter。实际上大致是这样的
    Object.definePrototype(Object.prototype, "__proto__", {
      get: function() {
        return Object.getPrototypeOf(this);
      },
      set: function() {
        // ES6中的 setPrototypeOf(...)
        Object.setPrototypeOf(this, o);
        return o;
      }
    })

    因此,访问 a.__proto__ 实际上是调用了 getter 函数,虽然 getter 函数存在于 Object.prototype 对象中,但是它的 this 指向对象 a,所以和 Object.getPrototypeOf(a) 结果相同。

  • 相关阅读:
    Selenium之IE浏览器的启动问题及解决
    Selenium之Chrome浏览器的启动问题及解决
    Selenium之IE浏览器的启动
    Selenium之firefox浏览器的启动
    【luogu 3373】【模板】线段树2
    【luogu 3372】【模板】线段树1
    【luogu 1908】逆序对
    【codevs2822】爱在心中
    【bzoj1051】 [HAOI2006]受欢迎的牛
    【luogu 2863】[USACO06JAN]牛的舞会The Cow Prom
  • 原文地址:https://www.cnblogs.com/wzndkj/p/12726415.html
Copyright © 2020-2023  润新知