【问题标题】:(String instanceof Object) returns true but I am not able to find the Object.prototype in String.prototype chain(String instanceof Object) 返回 true 但我无法在 String.prototype 链中找到 Object.prototype
【发布时间】:2015-04-22 08:10:02
【问题描述】:

我的 JavaScript 说 instanceof 运算符搜索原型属性是否存在于构造函数中。

String instanceof Object; // true
String.prototype                     === Object.prototype; // false
String.prototype.prototype           === Object.prototype; // false
String.prototype.prototype.prototype === Object.prototype; // Throws into "Cannot read property 'prototype' of undefined"

String.prototype.prototype; // undefined

这仅仅意味着 Object.prototype 不存在于 String.prototype 链上。 这让我很困惑,那么String instanceof Object 怎么会返回 true?

【问题讨论】:

    标签: javascript prototype instanceof


    【解决方案1】:

    你的 JavaScript 没有骗你 :D。确实,instanceof 运算符会测试 Constructor 的原型属性是否存在于 Object 原型链上。

    您只是错过了函数在 JavaScript 中具有双重生命的事实。它们同时也是函数和对象。当你在测试下面的代码时

    String instanceof Object; // 是的

    String 在上述代码中实际上是您所指的对象。现在让我们运行以下验证:

    String.__proto__ === Object.prototype; //假

    String.__proto__.__proto__ === Object.prototype; //真

    这就是您正在寻找的'true' :) 这反映了 Object.prototype 存在于 String 原型链上。

    注意:“Use proto with a caution

    The use of __proto__ is controversial, and has been discouraged by many. It was never originally included in the EcmaScript language spec, but modern browsers decided to implement it anyway. Today, the __proto__ property has been standardized in the ECMAScript 6 language specification and will be supported into the future. Still, mutating the [[Prototype]] of an object is a slow operation that should be avoided if performance is a concern.

    您可以尝试遍历原型链并避免 proto 的另一种方法如下:

    Object.getPrototypeOf(String.prototype) === Object.prototype;

    希望这会有所帮助。快乐的 JavaScript。

    【讨论】:

      【解决方案2】:

      是的,Stringinstanceof Object,因为 String 是一个函数,而函数是 JavaScript 中的对象。

      函数的prototype 属性不是该函数的原型。它是将被分配的对象,作为通过new 使用该函数创建的对象的原型。 (这个名字可能有点可惜,虽然这几年我还没想出更好的名字。)String的原型是Function.prototype(因为String是一个函数),我们可以看到使用ES5 的getPrototypeOf

      Object.getPrototypeOf(String) === Function.prototype // true
      

      我们还可以使用 ES6 的 __proto__ 属性(仅针对基于浏览器的引擎指定,但我怀疑非浏览器引擎无论如何都会支持它):

      String.__proto__ === Function.prototype // true
      

      这告诉我们String 是一个函数;但是我们怎么知道它是Object?因为函数是对象,所以:

      String.__proto__.__proto__ === Object.prototype // true
      Object.getPrototypeOf(Object.getPrototypeOf(String)) === Object.prototype // true
      

      所以您的.prototype.prototype 可以与.__proto__.__proto__ 一起使用:

      snippet.log(String.__proto__ === Function.prototype);         // true
      snippet.log(String.__proto__.__proto__ === Object.prototype); // true
      <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
      <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

      或者这里是一个使用非函数对象的多级层次结构示例:

      // NOTE! Snippet requires a modern browser that has the ES6 __proto__
      // property! Current Chrome, Firefox, and IE all do.
      
      function GrandParent() {
      }
      
      function Parent() {
        GrandParent.call(this);
      }
      Parent.prototype = Object.create(GrandParent.prototype);
      Parent.prototype.constructor = Parent;
      
      function Child() {
        Parent.call(this);
      }
      Child.prototype = Object.create(Parent.prototype);
      Child.prototype.constructor = Child;
      
      var c = new Child();
      snippet.log(c.__proto__ === Child.prototype);                           // true
      snippet.log(c.__proto__.__proto__ === Parent.prototype);                // true
      snippet.log(c.__proto__.__proto__.__proto__ === GrandParent.prototype); // true
      <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
      <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-13
        • 1970-01-01
        • 2015-07-28
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多