Почему __proto__ не объект - PullRequest
       18

Почему __proto__ не объект

2 голосов
/ 22 апреля 2019

Я поставил следующий код в 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__ может быть либо объектом, либо нулем, но здесь superClass является функцией.

Мой вопрос не является дубликатом, поскольку я не спрашиваю об object.prototype = function.prototype, но почему __proto__ = typeof function вместо object или null, как в спецификации

1 Ответ

2 голосов
/ 22 апреля 2019

Это для статических свойств / методов . Они также наследуются:

 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.setPrototypeOf является совершенно новым, как и class, поэтому его нельзя использовать для переноса. Вот почему в игру вступает свойство .__proto__: когда-то оно было добавлено Chrome для изменения прототипа объекта, и поскольку многие библиотеки приняли его использование, другие браузеры также реализовали его, и оно также было добавлено в спецификацию, хотя это считается ошибкой дизайна (кошмар производительности). На данный момент это единственный надежный способ передать свойства статического класса.

В будущем поддержка браузера для class, как мы надеемся, улучшится, и нам больше не придется полагаться на эти методы проникновения.

...