Несколько обычно используемых режимов создания объектов
Создать с новым ключевым словом
Самый базовый способ создания объектов - это не что иное, как то, что говорят большинство языков: если у вас нет объектов, вы можете стать новым!
var gf = new object (); gf.name = "tangwei"; gf.bar = "c ++"; gf.saywhatwhat = function () {console.log (this.name+"Sad: Love You Forever");}Создать с литералами
Это кажется правдой, но как гики могут такие сложные и низкоуровневые способы определения переменных? Как язык сценариев, он должен иметь тот же стиль, что и другие братья, поэтому появляется способ определения объектных литералов:
var gf = {name: "tangwei", bar: "c ++", скажите что: function () {console.log (this.name+"sad: love you forever"); }}Заводская модель
На самом деле, это наиболее часто используемый метод определения объекта в реальности, но что мне делать, если у меня есть много объектов с похожими атрибутами (интересно думать об этом ...)? Если одно определение сделано один за другим, будет сгенерировано большое количество кода. Почему бы не построить фабрику и массово производить наши объекты? Итак, первый надувный ребенок в мире JavaScript. Полем Полем Нет, «заводская модель» родилась!
Функция CreateGF (name, bar) {var O = new Object (); o.name = name; o.bar = bar; o.saywhat = function () {alert (this.name + "sad: love you forever"); } return o;} var gf1 = creategf ("bingbing", "d"); var gf2 = creategf ("mimi", "a");Конструктор
Заводской шаблон решает проблему создания нескольких похожих объектов, но проблема возникает снова. Все эти объекты формируются объектами. Как отличить конкретные типы их объектов? В настоящее время нам нужно переключиться на другой режим, режим конструктора:
Функция gf (name, bar) {this.name = name; this.bar = bar; this.saywhat = function () {alert (this.name + »сказал: Люблю тебя навсегда»); }} var gf1 = new gf ("vivian", "f"); var gf2 = new gf ("vivian2", "f");Здесь мы используем конструктор, начиная с заглавных букв, чтобы заменить CreateGF в приведенном выше примере. Обратите внимание, что первая буква конструктора должна быть зачислена в соглашение в соответствии с Конвенцией. Здесь мы создаем новый объект, затем назначаем объем конструктора новому объекту и называем методы в конструкторе.
Похоже, в приведенном выше методе нет ничего плохого, но мы можем обнаружить, что метод Saywhat в конструкторе, вызываемый в двух экземплярах, не является одним и тем же экземпляром функции:
console.log (gf1.saywhat == gf2.saywhat); //ЛОЖЬ
Вызов один и тот же метод, но объявление разных случаев - пустая трата ресурсов. Мы можем оптимизировать утверждение функции SAIWHAT за пределами конструктора:
Функция gf (name, bar) {this.name = name; this.bar = bar; this.saywhat = saywhat} функция говорит, что () {alert (this.name + "sad: love you forever");}Это решает проблему определения того же экземпляра метода несколько раз, но снова возникает новая проблема. Высказывание того, что мы определили, является глобальным методом объема, но этот метод не может быть вызван непосредственно, что немного противоречиво. Как более элегантно определить объект с определенной инкапсуляцией? Давайте посмотрим на шаблон объекта прототипа JavaScript.
Прототип объекта шаблона
Понять объекты прототипа
Когда мы создаем функцию, функция будет иметь атрибут прототипа, который указывает на объект прототипа функции, созданный через конструктор. С точки зрения непрофессионала, прототип объектов - это объекты в памяти, которые обеспечивают общие свойства и методы для других объектов.
В режиме прототипа нет необходимости определять атрибуты экземпляра в конструкторе, и информация о атрибуте может быть напрямую назначена объекту прототипа:
функция gf () {gf.prototype.name = "vivian"; Gf.prototype.bar = "c ++"; Gf.prototype.saywhat = function () {alert (this.name + "sad: love you forever"); }} var gf1 = new gf (); gf1.saywhathaT (); var gf2 = new gf ();Разница от конструктора заключается в том, что свойства и методы нового объекта могут быть разделены всеми экземплярами. Другими словами, GF1 и GF2 получают одинаковые свойства и методы. В дополнение к атрибутам, которые мы назначили, в объекте прототипа также есть некоторые встроенные атрибуты. Все объекты прототипа имеют атрибут конструктора, который является указателем на функцию, содержащую атрибут прототипа (не осмелитесь ли вы снова обойти точку!). Через картинку давайте четко разобраем процесс этого поворота:
Все объекты имеют прототип объекта (прототип). В объекте прототипа есть атрибут конструктора, указывающий на функцию, содержащую атрибут прототипа. Экземпляры GF GF1 и GF2 содержат внутренний атрибут, указывающий на объект прототипа (Proto появляется в виде личного атрибута в браузере Firefox). Когда мы получаем доступ к атрибуту в объекте, мы сначала спросим, есть ли у объекта экземпляра этот атрибут. Если нет, мы продолжим искать объект прототипа.
Использование объектов прототипа
В предыдущем примере мы заметили, что при добавлении свойств в объект прототипа нам нужно добавить GF.Prototype в каждый. Эта работа очень повторяющаяся. В приведенной выше шаблоне создания объекта мы знаем, что объект может быть создан в форме литералов. Здесь мы также можем его улучшить:
function gf () {} gf.prototype = {name: "vivian", bar: "c ++", скажите что: function () {alert (this.name+"sad: love you forever"); }}Есть место, где нам нужно обратить особое внимание. Атрибут конструктора больше не указывает на объект GF, потому что каждый раз, когда определяется функция, для него будет создан объект прототипа, и этот объект автоматически получит новый атрибут конструктора. В этом месте мы используем GF.Prototype, чтобы по существу перезаписать исходный объект прототипа, поэтому конструктор также стал атрибутом конструктора нового объекта, больше не указывая на GF, но объект: объект:
var gf1 = new gf (); console.log (gf1.constructor == gf); // falseconsole.log (gf1.constructor == Object) // true
Как правило, это тонкое изменение не повлияет на нас, но если у вас есть особые потребности в конструкторе, мы также можем явно указать свойство конструктора GF.Prototype:
Gf.prototype = {Constructor: GF, имя: «vivian», bar: «c ++», скажите что: function () {alert (this.name+»сказал: любите вас навсегда»); }} var gf1 = new gf (); console.log (gf1.constructor == gf); // trueБлагодаря предварительному пониманию шаблона объекта прототипа мы обнаружили, что все объекты экземпляра имеют одни и те же атрибуты, что является основной особенностью шаблона прототипа, но часто это «двойной меч» для разработчиков. В реальном развитии, случаи, которые, как мы надеемся, должны иметь свои собственные атрибуты, что также является основной причиной, по которой немногие люди используют только шаблон прототипа в реальном развитии.
Конструктор и прототип комбинации
В реальной разработке мы можем использовать конструкторы для определения свойств объектов и использовать прототипы для определения общих свойств и методов, чтобы мы могли передавать разные параметры для создания различных объектов, имея при этом общие методы и свойства.
Функция gf (name, bar) {this.name = name; this.bar = bar;} gf.prototype = {constructor: gf, скажите что: function () {alert (this.name + "sad: love you forever"); }} var gf1 = new gf ("vivian", "f"); var gf2 = new gf ("vivian1", "c");В этом примере мы определяем соответствующие значения свойств объектов в функции конструктора и определяем атрибут конструктора и говорим, какая функция в объекте прототипа, чтобы не было никакого влияния между атрибутами GF1 и GF2. Этот шаблон также является наиболее часто используемым методом определения объекта в реальной разработке, включая режим по умолчанию, принятый многими библиотеками JS (начальная загрузка и т. Д.).