Vários modos de criação de objetos comumente usados
Crie com nova palavra -chave
A maneira mais básica de criar objetos nada mais é do que o que a maioria dos idiomas diz: se você não possui objetos, poderá obter novos!
var gf = new Object (); gf.name = "tangwei"; gf.bar = "c ++"; gf.saywhat = function () {console.log (this.name+"sad: te amo para sempre");}Criar com literais
Isso parece ser verdade, mas como os geeks podem como uma maneira complexa e de baixo nível de definir variáveis? Como uma linguagem de script, deve ter o mesmo estilo que outros irmãos, então a maneira de definir os literais de objetos aparece:
var gf = {name: "tangwei", bar: "c ++", diga o que: function () {console.log (this.name+"sad: te amo para sempre"); }}Modelo de fábrica
Na verdade, este é o método de definição de objeto mais usado na realidade, mas o que devo fazer se tiver muitos objetos com atributos semelhantes (é emocionante pensar nisso ...)? Se uma definição for feita uma a uma, uma grande quantidade de código será gerada. Por que não construir uma fábrica e em massa produzir nossos objetos? Então, o primeiro bebê inflável no mundo JavaScript. . . Não, nasce o "modelo de fábrica"!
função creategf (nome, bar) {var o = new Object (); o.name = nome; O.Bar = bar; o.saywhat = function () {alert (this.name + "sad: te amo para sempre"); } retornar o;} var gf1 = creategf ("bingbing", "d"); var gf2 = creategf ("Mimi", "A");Construtor
O padrão de fábrica resolve o problema de criar vários objetos semelhantes, mas o problema ocorre novamente. Esses objetos são todos formados por objetos. Como distinguir os tipos específicos de seus objetos? No momento, precisamos mudar para outro modo, modo construtor:
função gf (nome, bar) {this.name = name; this.bar = bar; this.saywhat = function () {alert (this.name + "disse: te amo para sempre"); }} var gf1 = new gf ("Vivian", "f"); var gf2 = novo gf ("Vivian2", "f");Aqui, usamos um construtor começando com letras maiúsculas para substituir o CreateGF no exemplo acima. Observe que a primeira letra do construtor deve ser capitalizada de acordo com a convenção. Aqui, criamos um novo objeto, atribuímos o escopo do construtor ao novo objeto e chamamos os métodos no construtor.
Parece não haver nada de errado com o método acima, mas podemos descobrir que o método Saywhat no construtor chamado nas duas instâncias não é a mesma instância de função:
console.log (gf1.saywhat == gf2.saywhat); //falso
Chamar o mesmo método, mas declarar casos diferentes é um desperdício de recursos. Podemos otimizar a declaração do Saywhat Funciona fora do construtor:
função gf (nome, bar) {this.name = name; this.bar = bar; this.saywhat = Saywhat} Função diz o que () {alert (this.name + "sad: te amo para sempre");}Isso resolve o problema de definir a mesma instância do método várias vezes, mas um novo problema vem novamente. O ditado o que definimos é um método de escopo global, mas esse método não pode ser chamado diretamente, o que é um pouco contraditório. Como definir com mais elegância um objeto com determinado encapsulamento? Vamos dar uma olhada no padrão de objeto de protótipo JavaScript.
Padrão de objeto de protótipo
Entender objetos de protótipo
Quando criamos uma função, a função terá um atributo de protótipo, que aponta para o protótipo objeto da função criada através do construtor. Nos termos do Layman, os objetos de protótipo são objetos na memória que fornecem propriedades e métodos compartilhados para outros objetos.
No modo de protótipo, não há necessidade de definir atributos de instância no construtor, e as informações do atributo podem ser atribuídas diretamente ao objeto Prototype:
function gf () {gf.prototype.name = "Vivian"; Gf.prototype.bar = "c ++"; Gf.prototype.saywhat = function () {alert (this.name + "sad: te amo para sempre"); }} var gf1 = new gf (); gf1.saywhat (); var gf2 = new gf ();A diferença do construtor é que as propriedades e métodos do novo objeto podem ser compartilhados por todas as instâncias. Em outras palavras, GF1 e GF2 acessam as mesmas propriedades e métodos. Além dos atributos que atribuímos, também existem alguns atributos internos no objeto de protótipo. Todos os objetos de protótipo têm um atributo construtor, que é um ponteiro para uma função que contém o atributo de protótipo (se você ousa contornar o ponto novamente!). Através de uma foto, vamos resolver claramente o processo dessa torção:
Todos os objetos têm um protótipo objeto (protótipo). Há um atributo construtor no objeto protótipo apontando para uma função que contém o atributo do protótipo. As instâncias da GF GF1 e GF2 contêm um atributo interno apontando para o objeto de protótipo (o proto aparece como um atributo privado no navegador Firefox). Quando acessarmos o atributo em um objeto, primeiro perguntaremos se o objeto de instância possui esse atributo. Caso contrário, continuaremos a procurar o objeto de protótipo.
Usando objetos de protótipo
No exemplo anterior, notamos que, ao adicionar propriedades ao objeto de protótipo, precisamos adicionar GF.Prototype a cada um. Este trabalho é muito repetitivo. No padrão de criação de objetos acima, sabemos que um objeto pode ser criado na forma de literais. Aqui também podemos melhorá -lo:
function gf () {} gf.prototype = {name: "Vivian", bar: "c ++", diga o que: function () {alert (this.name+"sad: te amo para sempre"); }}Há um lugar onde precisamos prestar atenção especial. O atributo do construtor não aponta mais para o objeto GF, porque toda vez que uma função é definida, um protótipo será criado para ele ao mesmo tempo, e esse objeto obterá automaticamente um novo atributo construtor. Neste lugar, usamos o GF.Prototype para substituir essencialmente o objeto de protótipo original, para que o construtor também se torne o atributo construtor do novo objeto, não mais apontando para GF, mas objeto:
var gf1 = new gf (); console.log (gf1.constructor == gf); // Falseconsole.log (gf1.constructor == objeto) // true
Geralmente, essa mudança sutil não nos afetará, mas se você tiver necessidades especiais de construtor, também podemos especificar explicitamente a propriedade do construtor do GF.Prototype:
Gf.prototype = {construtor: gf, nome: "Vivian", bar: "c ++", diga o que: function () {alert (this.name+"disse: amo você para sempre"); }} var gf1 = new gf (); console.log (gf1.constructor == gf); // trueAtravés de um entendimento preliminar do padrão de objeto do protótipo, descobrimos que todos os objetos de instância compartilham os mesmos atributos, que é o recurso básico do padrão de protótipo, mas muitas vezes essa é uma "espada de dois gumes" para os desenvolvedores. No desenvolvimento real, os casos que esperamos ter seus próprios atributos, que também é a principal razão pela qual poucas pessoas usam o padrão de protótipo sozinho no desenvolvimento real.
Padrão de combinação de construtor e protótipo
No desenvolvimento real, podemos usar construtores para definir as propriedades dos objetos e usar protótipos para definir propriedades e métodos compartilhados, para que possamos passar parâmetros diferentes para criar objetos diferentes, enquanto tenham métodos e propriedades compartilhadas.
função gf (nome, bar) {this.name = name; this.bar = bar;} gf.prototype = {construtor: gf, diga o que: function () {alert (this.name + "sad: te amo para sempre"); }} var gf1 = new GF ("Vivian", "f"); var gf2 = new GF ("Vivian1", "C");Neste exemplo, definimos os respectivos valores de propriedade dos objetos na função do construtor e definimos o atributo do construtor e dizemos qual função no objeto de protótipo, para que não haja impacto entre os atributos GF1 e GF2. Esse padrão também é o método de definição de objeto mais comumente usado no desenvolvimento real, incluindo o modo padrão adotado por muitas bibliotecas JS (Bootstrap, etc.).