Доступ к родительскому (супер) методу в объекте, созданном Object.create - PullRequest
0 голосов
/ 03 октября 2018

Я хочу создать механизм обертки: мы обертываем c, поэтому новый новый объект w имеет собственные свойства и методы, но c также доступны.

// Note: this class might be from an external lib
class C {
  f() {
    console.log('f (original)');
    this.p = 'p';
  }
}

class W {
  f() {
    console.log('f (new)');
    super.f();  // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}

// Note: this value is external for us
const c = new C();

const w = Object.create(null, Object.getOwnPropertyDescriptors(W.prototype));
Object.setPrototypeOf(w, c);

w.f();  // expected:
        // f (new)
        // f (original)
        // p

Должен ли я сделатьэто правильно?

Почему происходит ошибка?

Обновление : PS Я понимаю, что могу использовать композицию, но хочу понять источник ошибки.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Почему возникает ошибка?

Поскольку метод W.prototype.f, использующий super, заботится только о прототипе W.prototype, чтобы оценить, что будет означать super,Ключевое слово super по сути является статическим поиском, в зависимости от объекта, в котором был объявлен метод, игнорируя цепочку прототипов объекта, для которого был вызван метод.

Если мы translate to

class W {
  f() {
    console.log('f (new)');
    Object.getPrototypeOf(W.prototype).f.call(this); // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}

мы можем видеть, что Object.prototype.f не является функцией ...


Таким образом, вы можете решить проблему, выполнив Object.setPrototypeOf(W.prototype, C.prototype) вместо Object.setPrototypeOf(w, c) (илиw = Object.create(c, …)), но я не могу этого рекомендовать.Если бы вы действительно хотели повлиять на все экземпляры, вы бы уже написали class W extends C (что привело бы к тому же результату, что и при использовании Object.setPrototypeOf(W.prototype, C.prototype)).

0 голосов
/ 03 октября 2018

вы хотите использовать ключевое слово extends, например:

    class C {
        f() { console.log( "C.f" ); }
    }

    class W extends C {
        f() {
            super.f()
            console.log( "W.f" );
        }
    }

    const w = new W();
    w.f(); // will output C.f W.f
...