为什么 __proto__ 不是对象

Why __proto__ not the object

我把下面的代码放到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如规范

它用于静态属性/方法。他们也继承了:

 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 属性的方法。

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