Nano Hash - криптовалюты, майнинг, программирование

Поведение прототипа Javascript

У меня есть метод, который позволит мне выбрать объект-прототип при создании нового объекта (скопировано из книги "Javascript: The Good Parts"):

Object.create = function(o) {
    var F = function() {};
    F.prototype=o;
    return new F();
}

Теперь скажем, у меня есть объект:

var car = {
   model: "Nissan"
};

И я создаю новый объект на основе этого объекта, используя метод «Создать»:

var car1 = Object.create(car);

Затем я могу добавить свойство к car, и оно будет динамически добавлено к car1 (динамическое прототипирование). Итак, например:

car.year=2011;      // Gets added to "car"...
alert(car1.year);   // ... Is also avaialable to car1

Q1) Такое поведение указывает на то, что "год" был добавлен к прототипу автомобиля, поэтому он доступен для car1. Это верно? Если нет, то куда добавляется «год» и почему он доступен как для «автомобиля», так и для «автомобиля1»?

Кроме того, согласно правилу делегирования, если метод не может быть найден для объекта, он будет искать его прототип, а затем проверять все прототипы вверх по цепочке, пока не дойдет до Object.prototype. Итак, теперь, если я наберу что-то вроде этого:

Object.prototype.originCountry = "Japan";
alert(car.originCountry);   // Outputs Japan
alert(car1.originCountry);  // Outputs Japan

Все идет нормально; однако, если я это сделаю:

Object.carColor= "White";
alert(car.carColor);   // Error!

Q2) Когда я добавляю свойство к "автомобилю" (см. пример car.year выше, оно добавляется к прототипу автомобиля. Однако, когда я добавляю свойство к объекту, оно не получает добавлен в прототип объекта? Если он добавляется в прототип объекта, то почему он недоступен для «автомобиля» в соответствии с правилом делегирования?

Почему это происходит?


  • Я думаю, что это поведение связано с тем, что свойства создаются на прототипе, и если вы пытаетесь создать их из самого объекта, он выдает undefined, и каждый раз, когда вы создаете свойство через прототип, каждый элемент, созданный с помощью этого прототипа, наследует его. 26.04.2012
  • Ваш Q2 начинается неправильно: вы ничего не добавили к прототипу car, вы добавили это к прототипу car1 (которым оказался car) 26.04.2012

Ответы:


1

Когда вы делаете это:

Object.carColor = "White";

Тогда свойство carColor не добавляется к прототипу Object. Теперь это собственность Object. Чтобы увидеть, что вы ожидаете, вы должны сделать следующее:

Object.prototype.carColor = "White";

Затем после этого:

alert(({}).carColor); // Will alert "White"

Так что здесь происходит вот что. любой созданный объект, включая {} (который представляет собой не что иное, как пустой объект), является новым экземпляром Object и, следовательно, разделяет свойства всего, что установлено в прототипе Object.

Что касается того, как работает ваша функция Object.create. Давайте посмотрим на это построчно:

 1. var F = function() {};

Вы просто создаете новую функцию, практически пустой объект. Причина, по которой вы используете функцию, а не что-то вроде {}, заключается в том, что функция может быть связана с вызовом new для создания нового экземпляра этого объекта, в котором функция будет действовать как конструктор.

2. F.prototype=o;

Вы устанавливаете прототип новой пустой функции в объект, который вы создали. Сейчас это чисто отсылка. Это не глубокая копия. Я имею в виду, что по мере изменения объекта o будут меняться и любые экземпляры объектов (на самом деле они не изменятся, но они будут «казаться» измененными. Подробнее об этом позже).

3. return new F();

Теперь вы просто создаете новый экземпляр этой функции, у которого есть прототип в качестве объекта, который вы передали.

Когда вы делаете следующее:

var car1 = Object.create(car);

Вы получаете объект car1, прототип которого имеет car. Итак, когда вы делаете это:

car.year = 2011

Это не похоже на car1 изменения. Это больше похоже на объект, на который прототип ссылается, изменения. Итак, когда вы делаете что-то вроде:

car1.year

Ищется (сначала в прототипе, потом в объекте) свойство с именем year и оказывается, что оно есть в прототипе и, следовательно, car1.year вернет 2011.

Итак, суть такова:

  1. Прототип распределяется среди экземпляров.
  2. Изменение свойств Object не приведет к изменению каких-либо экземпляров.
26.04.2012
  • Это то, что я пытаюсь понять. В своем посте вы сказали: [quote] Вы получаете объект car1 у которого есть прототип is car. Итак, когда вы делаете это: car.year = 2011 Это не похоже на изменение car1. Это больше похоже на объект, на который прототип ссылается, изменения. [/quote] Когда я что-то добавляю в автомобиль (car.prop=value), почему он добавляется в свой прототип, а когда я делаю то же самое в Object, то нет. @Берги 26.04.2012
  • По сути, происходит то, что car.year = 2011 теперь эквивалентно выражению car1.prototype.year = 2011, поскольку car1.prototype есть не что иное, как car. 26.04.2012
  • Извините за незнание этого, но почему car1.prototype === car? Функция create только устанавливает прототип нового объекта в существующий объект (в данном случае прототип car1 указывает на car1) 26.04.2012
  • Потому что это именно то, что происходит, когда вы делаете Object.create(car). По сути, вы создаете constructor, который в новом экземпляре вернет объект с car в качестве прототипа. 26.04.2012
  • Хорошо, но разве это не означает, что car1.prototype === car.prototype, а не car1.prototype === car. Спасибо за оперативные ответы! 26.04.2012
  • Нет. В строке 2 функции вы специально установили для прототипа значение o, а не o.prototype. Это означает car1.prototype === car и НЕ car1.prototype === car.prototype 26.04.2012
  • Не совсем. На car1 нет собственности prototype. Это внутренний указатель прототипа car1 (где свойства просматриваются, если они не найдены непосредственно в car1), который указывает на car, поскольку он был установлен как свойство конструктора (F) prototype. 27.04.2012

  • 2

    В первом примере вы добавляете к прототипу car1, потому что car === F.prototype и car1 instanceof F. Итак, вопрос 1: да.

    Object — это функция-конструктор всех объектов, как F для вашего car1. Если вы добавите что-то в Object.prototype, это будет доступно для всех объектов - вот почему вы не должны этого делать, такие неперечислимые свойства портят все for-in-loops. Если вы установите свойство функции-конструктора Object, ничего не изменится для вещей, которые наследуются от него. Не забывайте: Object соответствует функции F, а не параметру o для настройки прототипа. new Object() похож на Object.create(Object.prototype).

    26.04.2012

    3

    Эта функция не позволяет вам выбрать объект-прототип, она создает конструктор объекта nmew, аргумент объекта в качестве прототипа, а затем возвращает новый объект на основе конструктора.

    Этот новый объект унаследует методы и свойства от аргументов объекта. Это позволяет создавать новые объекты, которые наследуются от других.

    Причина, по которой это работает (и, кстати, объект является основным объектом javascript и не должен расширяться)

    Object.prototype.originCountry = "Japan";
    alert(car.originCountry);   // Outputs Japan
    alert(car1.originCountry);
    

    и это не

    Object.carColor= "White";
    

    это потому, что первый расширяет объект-прототип Object, что означает, что объект, построенный с помощью конструктора Object, наследует эти методы и свойства.

    В последнем случае мы называем статической функцией, которая не передается объекту, созданному из конструктора объекта.

    Я бы порекомендовал прочитать больше о прототипном наследовании в Javascript. вот мало ссылок.

    http://www.webreference.com/programming/javascript/prototypal_inheritance/index.html http://www.htmlgoodies.com/html5/tutorials/javascript-prototype-inheritance-explained.html#fbid=xEJ2PwtH2Oh

    http://unscriptable.com/2007/04/17/inheritance-explained/

    26.04.2012
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..