В большинстве языков программирования есть классы и объекты, и один класс может наследовать другие классы.
В Javascript наследование основано на прототипе, что означает, что в JavaScript нет классов, и вместо этого один объект наследует другой объект. :)
1. Наследство, прото
В JavaScript, когда кролика объекта наследует другое животное объект, это означает, что в объекте кролика будет особое свойство: кролик .__ Proto__ = животное;
При доступе к объекту кролика, если интерпретатор не может найти свойство в кролике, он будет следовать за цепочкой __proto__ для поиска в объекте животного
Атрибут __proto__ в каштанах доступен только в Chrome и Firefox. Пожалуйста, посмотрите каштан:
var Animal = {ets: true} var rabbit = {jumps: true} rabbit .__ Proto__ = Animal // inheritert (rabbit.eats) // trueАтрибут EATS доступен из объекта животного.
Если атрибут был найден в объекте кролика, то атрибут Proto не будет проверен.
Давайте получим еще один каштан. Когда в подклассе также появляется атрибут Eats, родительский класс не будет доступен.
var Animal = {eats: true} var fedUprabbit = {eats: false} fedUprabbit .__ Proto__ = Animal Alert (FedUprabbit.eats) // falseВы также можете добавить функцию в животное, и к ней также можно получить доступ к кролику.
var Animal = {eat: function () {alert ("It Full") this.full = true}} var rabbit = {jump: funct(1) Rabbit.eat ():
Функция Rabbit.eat () выполняется в следующих двух шагах:
Во -первых, переводчик ищет Rabbit.eat. У кролика нет функции еды, поэтому он смотрит вдоль кролика .__ Proto__ и нашла ее в животном.
Функция работает с этим = кролик. Это значение не имеет ничего общего с атрибутом __proto__.
Итак, это .full = true у кролика:
Давайте посмотрим, какие новые открытия мы сделали здесь. Объект вызывает родительскую функцию, но это все еще указывает на сам объект, который является наследством.
Объект, на который ссылается __proto__, называется прототипом, а животное - прототип кролика (примечание переводчика: это атрибут __proto__ кролика относится к атрибуту прототипа животного)
(2) Поиск при чтении, а не при написании
При чтении объекта, такого как этот.prop, интерпретатор ищет свойства в своем прототипе.
При настройке значения атрибута, например, это .prop = значение, тогда нет причин для поиска, и этот атрибут (PROP) будет добавлен непосредственно к этому объекту (это это). Удалить obj.prop аналогичен, он только удаляет свойства самого объекта, и свойства в прототипе остаются нетронутыми.
(3) о прото
Если вы читаете руководство, здесь мы называем __proto__, который представлен в руководстве как [[прототип]]. Обе скобки важны, потому что есть другое свойство, называемое прототипом.
2. object.create, object.getPrototypeof
__proto__-это нестандартное свойство, которое предоставляется Chrome/Firefox и остается невидимым в других браузерах.
Все современные браузеры, кроме Opera (то есть> 9) поддерживают две стандартные функции для решения проблем прототипа:
Object.ceate (rop [, ops])
Создайте пустой объект с данным прото:
var Animal = {Eats: true} rabbit = object.create (животное) оповещение (rabbit.eats) // trueПриведенный выше код создает пустой объект кролика, а прототип установлен на животное
После создания объекта кролика мы можем добавить к нему свойства:
var Animal = {ets: true} rabbit = object.create (животное) rabbit.jumps = trueВторой параметр функции Object.Creat не является необязательным, что позволяет устанавливать свойства как новые объекты. Это опущено из -за наследства наших отношений.
(1) object.getPrototypeof (obj)
Возвращает значение OBJ .__ Proto__. Эта функция является стандартной и может использоваться в браузерах, которые не могут непосредственно получить доступ к атрибуту __proto__.
var Animal = {Eats: true} Rabbit = Object.Create (Animal) Alert (object.getPrototypoof (rabbit) === Animal) // trueСовременные браузеры разрешают чтение значений атрибутов __proto__, но они не могут быть установлены.
3. Прототип
Есть несколько хороших способов поперечного браузера для установки атрибута __proto__, который будет использовать функции конструктора. помнить! Любая функция создает объект через новое ключевое слово.
Каштан:
Функция кролика (имя) {this.name = name} var rabbit = new Rabbit ('John') alert (rabbit.name) // ДжонНовая операция устанавливает свойства прототипа на свойство __proto__ объекта кролика.
Давайте посмотрим на его принцип, например, новый объект кролика, который наследует животные.
var Animal = {eats: true} функция Rabbit (name) {this.name = name} rabbit.prototype = Animalvar Rabbit = new Rabbit ('John') Alert (rabbit.eats) // true, потому что кролик.Rabbit.prototype = Literal Animal Literal: Set __proto__ = животное для всех объектов, созданных новым кроликом
4. Cross-Browser Object.create (Proto)
Функция Object.Create (PROP) является мощной, потому что она допускает прямое наследование от данного объекта. Это может быть смоделировано по следующему коду:
Функция наследство (proto) {function f () {} f.prototype = proto возвращает новый f}Унаследовать (животное) точно эквивалентно объекту. Create (животное), возвращает пустой объект и объект .__ Proto__ = животное.
Каштан:
var Animal = {eats: true} var rabbit = inherit (животное) alert (rabbit.eats) // trueAlert (rabbit.hasownproperty ('ets')) // false, из прототипаДавайте посмотрим на то, что это за принцип:
Функция наследника (proto) {function f () {} // (1) f.prototype = proto // (2) вернуть новое f () // (3)}(1) Была создана новая функция, и функция не установила никаких атрибутов для этого, поэтому `new F 'создаст пустой объект.
(2) `f.prototype` установлен на прото
(3) `new` f создает пустой объект, объект` __proto__ = f.protototype`
(4) Бинго! Мы получаем пустой объект, унаследованный «Прото»
Эта функция широко используется в различных библиотеках и рамках.
Ваша функция принимает объект с параметрами
/ * Параметры содержат настройки меню: ширина, высота и т. Д. */Меню функции (Options) {// ...} Вы хотите установить определенное меню функций параметров (Options) {Options.width = Options.width || 300 // Установить значение по умолчанию // ...}Полем Полем Полем Но изменение значения параметра может дать некоторые неправильные результаты, поскольку параметры могут использоваться во внешнем коде. Решение состоит в том, чтобы клонировать объект параметров, скопировать все атрибуты в новый объект и изменить его в новом объекте.
Как решить эту проблему с наследством? Параметры PS могут добавлять настройки, но не могут быть удалены.
Решение
Вы можете унаследовать параметры и изменить или добавить новые свойства в его подкласс.
Функция henhirit (proto) {function f () {} f.prototype = proto return new f} menu function (опции) {var opts = nehrit (options) opts.width = opts.width || 300 // ...}Все операции действительны только в субъектах. Когда метод меню заканчивается, внешний код все еще может использовать немодифицированные объекты параметров. Удалить операцию здесь очень важна. Если ширина является свойством в прототипе, Delete Opts.Width
5. Hasownproperty
Все объекты имеют функцию HasownProperty, которая может использоваться для определения того, является ли свойство самим или прототипом.
Каштан:
Функция Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = new Rabbit ('John') alert (rabbit.hasownproperty ('eats')) // false, в Prototyalert (Rabbit.hashownproperty ('name') // true, в объекте6. Цикл с/без наследственных свойств
для .. в выходе из цикла все свойства объекта, включая его собственный и прототип.
Функция Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = new Rabbit ('John') для (var p in rabbit) {alert (p + "=" + rabbit [p]) // Выходы оба «имя» и «ест»}Используйте HasownProperty для фильтрации свойств объекта:
Функция Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = new Rabbit ('John') для (var p in rabbit) {if (! rabbit.hasownproperty (p)) продолжить // fileter out "eats" alert (p + "=" + rabbit [p]) // Выходные ".7. Резюме
JavaScript реализует наследование через специальный атрибут Proto
При доступе к свойствам объекта, если интерпретатор не может найти его в объекте, он будет продолжать искать свойства функции, это указывает на объект, а не на его прототип.
Назначить obj.prop = value, удалить obj.prop
Управление прото:
Chrome и Firefox могут непосредственно получить доступ к атрибуту объекта __proto__. Большинство современных браузеров поддерживают доступ только для чтения с использованием object.getPrototypeof (obj).
Object.Create (proto) может генерировать пустые дочерние объекты с данным прото или достичь одной и той же функции с помощью следующего кода:
Функция наследника (proto) {function f () {} f.prototype = proto возвращает новое f ()}Другие методы:
Для .. в циклах выходов все свойства объекта (включая свой собственный и прототип) и прототип цепочки объекта.
Если опора собственности принадлежит объекту OBJ, то OBJ.HashownProperty (PROP) возвращает TRUE, в противном случае FALSE.