【问题标题】:Why __proto__ not the object为什么 __proto__ 不是对象
【发布时间】:2019-04-22 13:55:47
【问题描述】:

我把下面的代码放到babel:

class Animal {}

class Rabbit extends Animal {}

并将其转换为以下内容:

"use strict";

function _inheritsLoose(subClass, superClass) {
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype.constructor = subClass;
  subClass.__proto__ = superClass;
}

var Animal = function Animal() {};

var Rabbit =
  /*#__PURE__*/
  function(_Animal) {
    _inheritsLoose(Rabbit, _Animal);

    function Rabbit() {
      return _Animal.apply(this, arguments) || this;
    }

    return Rabbit;
  }(Animal);

问题是为什么它使用这一行 subClass.__proto__ = superClass; 并且根据文档 __proto__ 可以是对象或 null 但这里 superClass 是一个函数。

我的问题不是重复的,因为我不是在询问 object.prototype=function.prototype,而是在询问 __proto__ = typeof function 而不是 objectnull 规范

【问题讨论】:

标签: javascript ecmascript-6 prototype babeljs


【解决方案1】:

它用于静态属性/方法。它们也是遗传的:

 class Animal {
   static test() { }
 }

 console.log(Rabbit.test());

现在要正确转换,Rabbit 构造函数必须继承 Animal 构造函数。这通常没问题,因为函数也是对象,因此可以相互继承。不幸的是,没有办法创建一个继承另一个函数的函数,必须在之后设置:

 function Animal () { }
 Animal.test = function() { }

 function Rabbit() { }

 Object.setPrototypeOf(Rabbit, Animal);

 console.log(Rabbit.test());

现在下一个问题是,Object.setPrototypeOfclass 一样新,因此无法将其转译。这就是 .__proto__ 属性发挥作用的地方:它曾经被 Chrome 添加用于更改对象的原型,并且随着许多库采用这种用法,其他浏览器也实现了它,并且它也被添加到规范中,尽管它被认为是设计错误(性能噩梦)。这是目前唯一可靠的方式来转换静态类属性。

未来浏览器对class 的支持有望变得更好,我们不必再依赖这些转译技巧了。

【讨论】:

    猜你喜欢
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 2011-12-03
    • 1970-01-01
    • 2016-02-09
    • 2013-08-23
    • 1970-01-01
    相关资源
    最近更新 更多