Цепочка прототипа немного сбивает с толку, и есть много онлайн -информации. Каждый раз, когда я не могу спать по ночам, мне всегда нравится находить некоторые прототипные цепочки и закрывать статьи в Интернете, чтобы читать, что очень эффективно.
Не беспокойтесь об этих многочисленных терминах, это действительно не поможет вам, кроме как заставить ваш мозг изгиб. Просто посмотрите на прототипную цепь просто и примерно, и подумайте о вещах, которые не имеют ничего общего с кодом, например, с людьми, демонами и мужчинами в области транспорта.
1) Люди рождаются людьми, а монстры рождаются демонами. Люди и демоны - оба случая объектов, в то время как люди и демоны являются прототипами. Прототип также является объектом, называемым объектом прототипа.
2) Мать человека и его отец могут родить кучу детей, а мать -демон и его отец могут родить кучу детей. Жена мужчины и мужчина могут родить кучу детей. Человек - это конструктор, широко известный как человек.
3) Люди могут записать информацию о сексе, чтобы люди могли найти информацию о сексе через пол, то есть они могут найти конструктор через объекты прототипа.
4) Люди могут родить многих детей в своих матерях, но у этих детей есть только одна мать, которая является уникальностью прототипа.
5) Люди также рождаются людьми, они находят людей через людей, а затем находят людей через людей ... эти отношения называются прототипами.
6) Цепочка прототипа не бесконечна. Когда вы продолжаете смотреть через людей, вы обнаружите, что люди трахаются ... не чертовски людей, то есть прототип, наконец, указывает на NULL.
7) Люди, рожденные с мамой, будут выглядеть как люди, а монстры, рожденные с мамой, будут уродливыми. Это называется наследством.
8) Вы унаследовали цвет кожи вашей матери, ваша мать унаследовала цвет кожи вашей матери, вашей матери ..., это наследство цепи прототипа.
9) Если у вас нет дома, то ваш дом относится к дому вашей матери; Если у вашей матери нет дома, то ваш дом относится к дому вашей матери ... это восходящий поиск цепочки прототипа.
10) Вы будете унаследовать внешний вид своей матери, но вы также можете покрасить свои волосы, шампунь, порезать и дуть, то есть атрибуты объекта могут быть настроены и переопределит унаследованные атрибуты.
11) Хотя вы вымыли, подстригли, взорвали и окрашены в желтые волосы, вы не можете изменить внешность своей матери. Младший брат и сестра, рожденные от вашей матери, не имеют ничего общего с вашим желтым мытьем волосами, стрижкой и взорванными желтыми волосами, то есть объект не может изменить свойства прототипа.
12) Но если ваш дом сожжен вами, это означает, что ваша мать и ваши братья сожжены, и это обмен атрибутами прототипа.
13) Прозвище вашей матери - Ажэнь, и тетя ее соседа называет вас Аженером, но после того, как волосы вашей матери повернулись от Пиаору к королю Золотого льва, тетя по соседству изменила ее слова и назвала вас принцем Золотого Льва. Это называется динамической природой прототипа.
14) Твоя мама любит красоту и отправилась в Корею для пластической операции. Она даже не могла узнать свою мать. Даже если волосы вашей матери сменились к мягкости, сосед по соседству по -прежнему назвал вас Принцем Золотого льва. Поскольку никто не узнал твою мать, твоя мать вернулась на фабрику после пластической операции. Это общее переписывание прототипа.
Блин! Ты достаточно! Не bb! Покажи мне код!
Функция человека (имя) {this.name = name; } function mother () {} mother.prototype = {// Материнский прототип прототипа: 18, дом: ['beijing', 'shanghai']}; person.prototype = new Mother (); // Прототип человека - мать // Использование инструмента отладки Chrome для просмотра прототипа, предоставляя интерфейс __proto__ для просмотра прототипа var p1 = new Person ('jack'); // p1: 'jack'; __proto __: 18, ['' beijing ',' shanghai '] var p2 = новый человек («mark»); // p2: 'mark'; __proto __: 18, ['beijing', 'shanghai'] p1.age = 20; /* Экземпляр не может изменить атрибут базового значения прототипа, так же, как вы мыть, стричь, взорвать и окрасить желтые волосы не имеют ничего общего с вашей матерью* Обычная операция добавления возрастного атрибута в экземпляр P1 не имеет ничего общего с прототипом. То же, что и var o {}; O.Age = 20. * P1: ниже возраст атрибута ниже, а __proto__ такой же, как мать. Прототип, возраст = 18. * P2: только имя атрибута, __proto__ - это то же самое, что и мать. Прототип*/p1.home [0] = 'shenzhen'; /* Совместное использование атрибутов типа ссылки в прототипе так же, как вы сжигаете свой дом, он сжигает дом всей вашей семьи* Это немного проход, давайте осторожно забраем его? * P1: 'Jack', 20; __proto __: 18, ['shenzhen', 'shanghai']* p2: 'mark'; __proto __: 18, ['shenzhen', 'shanghai']*/p1.home = ['Hangzhou', 'guangzhou']; /* Фактически, та же операция, что и p1.age = 20. Изменить это понимание: var o {}; o.house = ['Big', 'house']* p1: 'jack', 20, ['Hangzhou', 'guangzhou']; __proto __: 18, ['shenzhen', 'shanghai']* p2: 'mark'; __proto __: 18, ['shenzhen', 'shanghai']*/delete p1.age; /* После удаления пользовательских атрибутов первоначально переписанное значение прототипа будет повторно эксплуатировано. Это механизм поиска вверх, так что существует следующая динамика* P1: «jack», ['Hangzhou', 'guangzhou']; __proto __: 18, ['shenzhen', 'shanghai']* p2: 'mark'; __proto __: 18, ['shenzhen', 'shanghai']*/person.prototype.lastname = 'Jin'; /* Перепишите прототип и динамически реагируйте на экземпляр. Подобно тому, как ваша мать стала модным человеком, соседи говорят, что вы сын модной женщины, когда они упоминают об этом* Обратите внимание, что мы переписываем здесь прототип человека, который должен добавить атрибут Lastname к матери, что эквивалентно Mother.lastname = 'Jin'* Это не меняет Mother.prototype. Если вы измените разные уровни, эффекты часто будут очень разными. * p1: 'jack', ['Hangzhou', 'guangzhou']; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']* p2: 'mark'; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']*/person.prototype = {aster: 28, адрес: {usa: 'usa', city: 'washington'}}; var p3 = новый человек ('obama'); /* Перепишите прототип! В настоящее время прототип человека полностью стал новым объектом, что означает, что человек изменил свою мать. * Чтобы понять это так: var a = 10; b = a; a = 20; c = а. Таким образом, B остается неизменным и становится C, поэтому P3 меняется и не имеет ничего общего с матерью. * p1: 'jack', ['Hangzhou', 'guangzhou']; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']* p2: 'mark'; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']* p3: 'obama'; __ proto__: 28 {country: 'usa', город: «Вашингтон '}*/mother.prototype.no = 9527;/* Пересмотр прототипа и динамически. Подобно тому, как ваша мать стала новой тенденцией, соседи говорят, что вы действительно модная бабушка* Обратите внимание, что мы переписываем мать. * p1: 'jack', ['Hangzhou', 'guangzhou']; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai'], 9527* p2: 'mark'; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai'], 9527* p3: 'obama'; __proto__: 28 {страна: 'usa', город: 'washington'}*/mother.prototype = {car: 2, hobby: ['run', 'walk']}; var p4 = новый человек ('tony');/* Перепишите прототип прототипа! В настоящее время прототип матери полностью стал новым объектом! * Поскольку человек и мать были отключены сверху, изменение матери больше не повлияет на человека. * P4: 'Tony'; __ Proto__: 28 {страна: 'USA', город: 'washington'}*/person.prototype = new Mother (); // Привязать var снова p5 = новый человек ('luffy'); // Если вам нужно применить эти изменения в настоящее время, вы должны повторно подключить прототип человека к матери // p5: 'luffy'; __ proto__: 2, ['run', 'Walk'] P1 .__ Proto __.__ Proto ____ Proto ____ Proto ____. Мать .__ Proto __.__ Proto __.__ Proto__ // null, как вы думаете, конечная точка цепочки прототипа не является нулевой?Вы можете понять после прочтения?
Теперь давайте поговорим о разнице между p1.age = 20, p1.home = ['Hangzhou', 'guangzhou'] и p1.home [0] = 'shenzhen'. p1.home [0] = 'shenzhen'; Подводя итог, это форма, такая как p1.object.method, p1.object.property.
p1.age = 20; p1.home = ['Hangzhou', 'guangzhou']; Эти два предложения легко понять. Сначала забудьте прототип и подумайте о том, как мы добавляем атрибуты в обычный объект:
var obj = new Object (); obj.name = 'xxx'; obj.num = [100, 200];
Вы так понимаете? Это то же самое.
Тогда почему p1.home [0] = 'shenzhen' не создает собственность домашнего массива под P1, а затем установил свою первую позицию в «Шэньчжэнь»? Давайте забудем это первым, подумайте об объекте OBJ выше. Если это написано так: var obj.name = 'xxx', obj.num = [100, 200], вы можете получить желаемый результат? Очевидно, вы ничего не получите, кроме ошибки. Поскольку OBJ еще не был определен, как вы можете что -то добавить в это? Точно так же дом в P1.home [0] не определяется в P1, поэтому невозможно напрямую определить дом [0]. Если вы хотите создать домашний массив под P1, конечно, он написан так:
p1.home = []; p1.home [0] = 'shenzhen';
Разве это не наиболее часто используемый метод?
Причина, по которой P1.home [0] = 'Shenzhen' напрямую не сообщает об ошибке, заключается в том, что в цепочке прототипа есть механизм поиска. Когда мы вводим p1.object, механизм поиска цепочки прототипа заключается в том, чтобы сначала искать соответствующее значение в экземпляре. Если его нельзя найти, он будет искать в прототипе. Если его нельзя найти, он будет искать на предыдущем уровне цепочки прототипа ... он достигнет конца цепочки прототипа, то есть, если она еще не найдена, он вернет неопределенную. Когда мы вводим p1.home [0], тот же механизм поиска также верен. Сначала найдите P1, чтобы увидеть, есть ли какие -либо атрибуты и методы, названные Home, а затем искать вверх шаг за шагом. Наконец, мы нашли его в прототипе матери, поэтому модификация его эквивалентна модификации прототипа матери.
В итоге: p1.home [0] = 'shenzhen' эквивалентен Mother.prototype.home [0] = 'shenzhen'.
Из приведенного выше анализа мы видим, что основная проблема наследования прототипа цепи заключается в обмене атрибутами. Много раз мы хотим поделиться только методами, но не атрибутами. В идеале, каждый экземпляр должен иметь независимые атрибуты. Следовательно, есть два способа улучшения прототипа наследования:
1) Комбинированное наследование
Функция матери (возраст) {this.age = age; this.hobby = ['running', 'football']} mother.prototype.showage = function () {console.log (this.age); }; function person (имя, возраст) {mother.call (это, возраст); // второе выполнение this.name = name; } Person.prototype = new Mother (); // First Exection Person.prototype.constructor = Person; Person.prototype.showname = function () {console.log (this.name);} var p1 = new Person ('jack', 20); p1.hobby.push ('баскетбол'); // p1: 'jack'; __proto __: 20, ['running', 'football'] var p2 = новый человек («Марк», 18); // p2: 'mark'; __proto __: 18, [«бег», «футбол»]Результат фиолетовый:
Когда здесь выполняется первое выполнение, вы получаете человека .prototype.age = undefined, person.prototype.hobby = ['running', 'football']. Второе исполнение - это то, что var p1 = новый человек ('jack', 20), и вы получаете p1.age = 20, p1.hobby = ['running', 'football']. После толчка он становится p1.hobby = ['running', 'football', 'баскетбол']. На самом деле, относительно просто понять изменения этого. Вы можете получить этот результат, просто заменив это. Если вы чувствуете, что это немного сбивает с толку, попробуйте выбрасывать концепции в свой разум и выполнить код сверху вниз в качестве браузера. Это выйдет?
Выполнив прототип Constructor Mother () во второй раз, мы скопировали копию свойств прототипа в экземпляре объекта, чтобы мы могли отделиться и отделиться от свойств прототипа. Если вы осторожны, вы обнаружите, что в первый раз, когда мы позвонили Mother (), кажется, что нет никакого использования. Как мы не можем это назвать? Да, существует следующая паразитическая комбинация наследия.
2) Наследство паразитической комбинации
Функциональный объект (o) {function f () {} f.prototype = o; return new f ();} function inheritprototype (человек, мать) {var prototype = object (mother.prototype); Prototype.constructor = человек; Person.prototype = Prototype; } function Mother (возраст) {this.age = age; this.hobby = ['running', 'football']} mother.prototype.showage = function () {console.log (this.age); }; function person (имя, возраст) {mother.call (это, возраст); this.name = name; } inheritPrototype (человек, мать); Person.prototype.showname = function () {console.log (this.name);} var p1 = new Person ('jack', 20); p1.hobby.push ('баскетбол'); // p1: 'jack'; __proto __: 20, ['running', 'football'] var p2 = новый человек («Марк», 18); // p2: 'mark'; __proto __: 18, [«бег», «футбол»]Результат фиолетовый:
В прототипе больше нет атрибутов возраста и хобби, есть только два метода, которые являются именно тем результатом, который мы хотим!
Ключевой момент заключается в объекте (O), где здесь заимствован временный объект, чтобы умело избегать вызова New Mother (), а затем возвращать новый экземпляр объекта с прототипом O, тем самым завершая настройку цепочки прототипа. Это очень сбивает с толку, верно? Это потому, что мы не можем установить человека.
краткое содержание
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
Сказав так много, на самом деле есть только одно ядро: совместное использование атрибутов и независимый контроль. Когда ваш экземпляр объекта нуждается в независимых атрибутах, суть всех практик состоит в том, чтобы создавать атрибуты в экземпляре объекта. Если вы не думаете слишком много, вы можете напрямую определить независимые атрибуты, которые вам нужны лично, чтобы перезаписать свойства прототипа. Короче говоря, при использовании прототипа наследования вы должны уделять особое внимание атрибутам в прототипе, потому что это все существования, которые влияют на все тело.
Ниже приведен простой список различных методов создания объектов в JS. Наиболее часто используемым методом сейчас является комбинированный режим. Знакомые студенты могут пропустить до конца статьи и понравиться.
1) Оригинальный режим
// 1. Оригинальный режим, объектный буквальный режим var person = {name: 'jack', возраст: 18, sayname: function () {alert (this.name); }}; // 1. Исходный режим, режим конструктора объекта var person = new Object (); person.name = 'jack'; Человек.age = 18; person.sayname = function () {alert (this.name);};Очевидно, что когда мы хотим создавать партии Person1, Person2 ..., мы должны набирать много кода каждый раз, и даже старшие колпастеры не могут этого вынести! Тогда есть заводская модель массового производства.
2) Заводская модель
// 2. Заводский режим, определите функцию для создания функции объекта CreatePerson (name, age) {var temp = new Object (); person.name = name; person.age = age; person.sayname = function () {alert (this.name);}; return temp; }Фабричный режим-это массовое производство, и вы можете войти в режим создания человека с помощью простого вызова (Papapapa ...). Вы можете создать кучу детей, указав свое имя и возраст, и освободить руки. Однако, поскольку он работает на фабрике, вы не можете определить, какой тип объекта, будь то человек или собака (экземпляр теста является объектом). Кроме того, каждый раз, когда вы создаете человека, вы должны создавать независимый объект температуры, код раздувается, а бабочка элегантна.
3) Конструктор
// 3. Режим конструктора, определите функцию конструктора для функции объекта (имя, возраст) {this.name = name; this.age = age; this.sayname = function () {alert (this.name);}; } var p1 = новый человек ('jack', 18); // Создать человека P1 («Джек», 18); // Методы атрибутов приведены в Ondow Object, window.name = 'jack', window.sayname ()Конструктор похож на конструкторы классов в C ++ и Java, и его легко понять. Кроме того, человек может использоваться в качестве распознавания типа (экземпляр теста является человеком и объектом). Тем не менее, все экземпляры все еще независимы, и методы разных случаев на самом деле являются разными функциями. Забыли слово «функция» здесь, просто относитесь к Sayname как объект и поймите ее. То есть, SayName Zhang San и SayName Ли Си имеют разные существования, но, очевидно, то, что мы ожидаем, состоит в том, чтобы поделиться SayName, чтобы сохранить память.
4) Прототип режим
// 4. Режим прототипа, непосредственно определяйте функцию атрибута прототипа Person () {} person.prototype.name = 'jack'; person.prototype.age = 18; person.prototype.sayname = function () {alert (this.name); }; // 4. Прототип, метод буквального определения функция () {} person.prototype = {name: 'jack', возраст: 18, sayname: function () {alert (this.name); }}; var p1 = new Person (); // name = 'jack'var p2 = new Person (); // name = 'jack'Здесь необходимо отметить, так это обмен атрибутами и методами прототипа, то есть все случаи относятся только к методам атрибутов в прототипе, и изменения, генерируемые в любом месте, будут вызывать изменения в других случаях.
5) Смешанный режим (конструкция + прототип)
// 5. Прототип конструкции комбинации режима, функция человека (имя, возраст) {this.name = name; this.age = age;} person.prototype = {hobby: ['running', 'football']; sayname: function () {alert (this.name); }, sayage: function () {alert (this.age); }}; var p1 = новый человек ('jack', 20); // p1: 'jack', 20; __proto__: ['running', 'Football'], Sayname, Sayagevar P2 = новый человек («Марк», 18); // p1: 'mark', 18; __ proto__: ['running', 'football'], sayname, sayageПодход заключается в том, чтобы поместить методы свойства, которые должны быть независимыми в конструктор, а части, которые могут быть обмены, помещаются в прототип. Это может максимизировать экономию памяти, сохраняя независимость экземпляров объекта.