Javascript прототипи, конструктори

Відразу після того, як ми створили функцію, у неї є властивість prototype. куди записаний деякий об'єкт:

Правда, це властивість як той ховрашок, який є не дивлячись на те, що його не бачиш:

Якщо спробувати вивчити, як влаштований об'єкт, який сидить в цій властивості, може здатися, що він - порожній:

Будь Пихарь з упевненістю скаже "Ми створили об'єкт а, що є екземпляром класу Foo". Насправді в 7 символах "new Foo" укладена наступна магія:

  • Ми створюємо порожній об'єкт (як якщо б написали a = <> )
  • Прототипом цього об'єкта призначається то, що сидить в Foo.prototype
  • Цей об'єкт прив'язується до this в тілі Foo
  • Виповнюється функція Foo
  • Оператор new повертає створений об'єкт, якщо Foo не повернула що-небудь інше.
  • "Прототип" з пункту 2 - це такий об'єкт, де будуть шукатися властивості створеного об'єкта a. які він сам в явному вигляді не містить. Код нижче ілюструє все це більш розгорнуто:

    ОК, ніби розібралися, що таке "прототип об'єкта", звідки він береться і навіщо потрібен. А як його подивитися? В ідеальному світі ми могли б звернутися до obj.prototype і отримати прототип об'єкта. Але на жаль, як ми бачили вище, властивість з такою назвою використовується інакше - зберігає те, що функція-конструктор зробить прототипом об'єкта. Напрошується висновок, що можна отримати прототип через .prototype конструктора. спробуємо:

    Начебто працює. Але що, якщо ми намагалися зобразити спадкування, розширивши Foo іншим "класом"?

    Саме час замислитися, куди, власне, вказує a.constructor. А, власне, нікуди не вказує, тому що у a нету такого властивості, воно береться з ланцюжка прототипів. В наведеному вище прикладі "прототип a" - це екземпляр Bar (бо в Foo.prototype результат виконання new Bar). У примірника Bar теж немає властивості constructor. Зате воно є у прототипу примірника Bar - бо Bar.prototype (прототип примірника Bar) має властивість .constructor, яке вказує на Bar ( "властивість-ховрах", про який я писав на самому початку).

    Якщо подумати, факап в цьому прикладі трапився через те, що ми "розширили" "клас" "екземпляром" (так, все - в лапках!). Логічніше "розширювати" "клас" "класом", але суті це не міняє - на obj.constructor.prototype в пошуках прототипу ми покладатися не можемо. Тому що obj.constructor - це не "функція, яка створила obj", а в кращому випадку - "функція, яка створила прототип obj" (так сформульовано в доках на MDN). У кращому випадку - тому що, взагалі-то, там може бути що завгодно:

    До появи цієї штуки у розробників було тільки властивість .__ proto__, яке працює тільки в Mozilla-образних браузерах.

    Настав час для типу-саммарі.

    Що таке "прототип об'єкта obj"?
    Це об'єкт, до якого JS звертається за властивостями, яких немає у самого obj.

    Що таке obj.prototype?
    Якщо obj - це функція, то obj.prototype - то, що стане прототипом об'єкта при виклику new obj ().

    Як кросбраузерності отримати посилання на прототип об'єкта?
    Ніяк :) благо не часто потрібно.

    Що таке obj .__ proto__?
    Це прототип об'єкта obj, якщо у вас Мозилла

    Що таке Object.getPrototypeOf (obj)
    Це спосіб отримати посилання на прототип об'єкта obj, який стане кросбраузерності після смерті IE8 (ну FF до 3.5)

    Навіщо мені все це знати? о_0
    Якщо створення сайтів - ваша робота, то. вам це все знати нафіг не потрібно :) Якщо тільки для загальної освіченості, ну і щоб голову поламати на дозвіллі.

    Я б сказав правильніше так - загадкове опис специфікацій JS. І звичайно додайте сюди низьке якості перекладу (за що до речі не можна звинувачувати тільки перекладачів).

    Створюється враження. що творці мови роблять все, що б в ньому користувачам було важко розібратися.

    До нових і нестандартним. але логічним у середовищі ООП поняттям. слід на мій погляд віднести - поліморфізм.

    "Відразу після того, як ми створили функцію, у неї є властивість prototype, куди записаний деякий об'єкт:"

    Властивість prototype функція має завжди. Не забуваємо. функція сама є об'єктом.

    "ОК, ніби розібралися, що таке" прототип об'єкта ", звідки він береться і навіщо потрібен. А як його подивитися? В ідеальному світі ми могли б звернутися до obj.prototype і отримати прототип об'єкта. Але на жаль, як ми бачили вище, властивість з такою назвою використовується інакше - зберігає те, що функція-конструктор зробить прототипом об'єкта. "

    Не знаю описка тут або помилка. Але слід обов'язково зазначити - у створеного за допомогою функції об'єкта властивість з ім'ям prototype теж є. Але ця властивість вказує вже на наступний вищий об'єкт в ланцюжку прототипів (як правило Object).

    Не знаю описка тут або помилка. Але слід обов'язково зазначити - у створеного за допомогою функції об'єкта властивість з ім'ям prototype теж є. Але ця властивість вказує вже на наступний вищий об'єкт в ланцюжку прототипів (як правило Object).

    Будь ласка Приберіть цей абзац з попереднього. він звичайно помилковий і стосується об'єкта прототипу