Ao criar objetos através de construtores de objetos ou literais de objeto, ao criar muitos objetos com a mesma interface, será gerada uma grande quantidade de código duplicado. Por simplicidade, o modelo de fábrica foi introduzido.
Modelo de fábrica
função createPerson (nome, idade, trabalho) {var obj = new Object (); obj.name = nome; obj.age = idade; obj.job = job; obj.sayhello () {alert (this.name); }; retornar obj;} var p1 = createPerson ("xxyh", 19, "programador"); var p2 = createperson ("zhangsan", 18, "aluno");Essa maneira de criar objetos simplifica bastante o código, mas também há uma falha, ou seja, o tipo de objeto não pode ser determinado. Para resolver esse problema, o seguinte padrão é exibido.
Modo construtor
Crie um construtor personalizado para definir propriedades e métodos de tipos de objetos personalizados.
função pessoa (nome, idade, trabalho) {this.name = name; this.age = idade; this.Job = Job; this.sayName = function () {alert (this.name); };} var p1 = new Pessoa ("xxyh", 19, "Programador"); var p2 = new Pessoa ("Jack", 18, "Student");No exemplo acima, a pessoa () substitui CreatePerson (). Além disso, existem várias diferenças:
• Crie objetos sem exibição;
• Atribuir diretamente atributos e métodos a este objeto
• Nenhuma declaração de retorno
Para criar um objeto de pessoa, você deve usar o novo operador. É dividido em 4 etapas:
• Crie um novo objeto
• Atribuir o escopo do construtor a um novo objeto
• Executar o código no construtor
• Retornar novo objeto
P1 e P2, respectivamente, salve uma instância de pessoa.
alerta (P1.Constructor == Pessoa); // Truealert (p2.Constructor == Pessoa); // verdadeiro
É melhor usar a instância do tipo de detecção de tipos:
alerta (objeto P1 Instânciaof); // Truealert (P1 Instância de pessoa); // Truealert (objeto P2 Instânciaof); // Truealert (P2 Instância de pessoa); // Truealert (P2 Instância de pessoa); // verdadeiro
P1 e P2 são instâncias de objeto, porque todos os objetos são herdados do objeto.
2.1 Trate os construtores como funções
// use var pessoa = new pessoa ("xxyh", 19, "programador"); pessoa.SayName (); // "xxyh" // usa como uma pessoa de função normal ("zhangsan", 18, "estudante"); // Adicione a windowwindow.sayname (); // "zhangsan" // chama var obj no escopo de outro objeto obj = new Object (); Person.Call (OBJ, "Jack", 29, "Gerente"); obj.sayName (); // "jack", obj tem todas as propriedades e métodos2.2 Problema do construtor
O problema com o uso de construtores é que cada método precisa ser recriado em cada instância. P1 e P2 têm um método SayName (), mas não são uma instância de função. No JavaScript, uma função é um objeto; portanto, toda vez que uma função é definida, um objeto é instanciado.
O construtor também pode ser definido assim:
função pessoa (nome, idade, trabalho) {this.name = name; this.age = idade; this.Job = Job; this.sayName = new Função ("Alert (this.name)");}Portanto, as funções de mesmo nome em diferentes instâncias não são iguais:
alerta (P1.SayName == P2.SayName); // false
No entanto, a criação de duas funções com a mesma função é redundante e não há necessidade de vincular a função a um objeto específico antes de executar o código.
função pessoa (nome, idade, trabalho) {this.name = name; this.age = idade; this.Job = Job; this.sayName = SayName;} função dizName () {alert (this.name);} var p1 = new Person ("xxyh", 19, "programador"); var p2 = nova pessoa ("jack", 18, "aluno");O exposto acima move a definição de SayName () para fora do construtor e, em seguida, define o atributo SayName como a função Global Sayname dentro do construtor. Dessa maneira, o SayName contém um ponteiro para a função, e P1 e P2 compartilham a mesma função SayName () definida no escopo global.
No entanto, há um novo problema com isso: as funções definidas no escopo global só podem ser chamadas por um determinado objeto. E se o objeto define muitos métodos, o tipo de referência perde seu encapsulamento.
Modo de cadeia de protótipo
Cada função possui uma propriedade de protótipo, que é um ponteiro apontando para um objeto. O objetivo deste objeto é incluir propriedades e métodos que podem ser compartilhados por todas as instâncias de um tipo específico . O protótipo é o objeto de protótipo dessa instância de objeto criada chamando o construtor. A vantagem de usar um objeto de protótipo é que todas as instâncias de objeto podem compartilhar as propriedades e métodos que ele contém. Isso significa que, em vez de definir as informações da instância do objeto no construtor, essas informações são adicionadas ao objeto de protótipo.
function pessoa () {} pessoa.prototype.name = "xxyh"; Pessoa.prototype.age = 19; Person.prototype.job = "Programmer"; Person.prototype.SayName = function () {alert (this.name);}; var pessoa1 = novo (); PERSON.SAYNAME (); // "xxyh" var pessoa2 = new Person (); pessoa2.SayName (); // "xxyh" alert (Person1.SayName == Person2.SayName); // verdadeiro3.1 Entendendo objetos de protótipo
Basta criar uma nova função, uma propriedade protótipo será criada para a função, que aponta para o objeto de protótipo da função. Por padrão, todos os objetos do protótipo obterão automaticamente uma propriedade construtora. Esta propriedade contém um ponteiro para a função em que a propriedade do protótipo está localizada. Pessoa.prototype.Constructor aponta para a pessoa.
Quando o construtor é chamado para criar uma instância, o interior da instância conterá um ponteiro (propriedade interna) ao objeto de protótipo do construtor, chamado [[protótipo]]. Acessado via _proto no Firefox, Safari e Chrome. Essa conexão existe entre a instância e o objeto de protótipo do construtor, não entre a instância e o construtor.
A figura a seguir mostra a relação entre cada objeto:
Person.Prototype aponta para o objeto Prototype, e PERSON.Prototype.Constructor aponta para a pessoa. Além do atributo construtor, existem outros atributos adicionados no protótipo. As instâncias da pessoa contêm uma propriedade interna que aponta apenas para a pessoa. Prototipo e não têm relacionamento direto com o construtor.
Embora [[protótipo]] não possa ser acessado, o método isProTypeOf () pode ser usado para determinar se existe uma relação entre objetos.
alerta (Person.prototype.isprototypeof (Person1)); // Truealert (Person.prototype.isprototypeof (Person2)); // verdadeiro
Ao ler as propriedades de um objeto, uma pesquisa é realizada, com o objetivo do atributo com o nome fornecido. A pesquisa começa com a própria instância do objeto. A pesquisa começa na própria instância do objeto. Se um atributo com o nome fornecido for encontrado na instância, o valor do atributo será retornado; Se não for encontrado, continue pesquisando o objeto protótipo apontado pelo ponteiro e procure o atributo com o nome fornecido no objeto Prototype. Se essa propriedade for encontrada no objeto de protótipo, o valor da propriedade será retornado.
Os valores salvos no protótipo podem ser acessados através da instância do objeto, mas os valores armazenados no protótipo não podem ser reescritos através da instância do objeto . Se você adicionar um atributo à instância com o mesmo nome que um atributo no protótipo da instância, o atributo bloqueará o atributo no protótipo.
function pessoa () {} pessoa.prototype.name = "xxyh"; pessoa.prototype.age = "20"; Pessoa.Prototype.job = "Programmer"; Person.prototype.sayname = function () {alert (this.name);}; var) = novo (); "oooo"; alerta (pessoa1.name); // alerta "oooo" (Person2.Name); // "xxyh"No exemplo acima, o atributo de nome em Person1 bloqueia o atributo Nome no protótipo.
Quando um atributo é adicionado a uma instância do objeto, esse atributo bloqueia os atributos do mesmo nome salvo no objeto Prototype. Isso significa que a existência dessa propriedade impedirá o acesso a essa propriedade no protótipo. Use Excluir para excluir propriedades da instância.
function pessoa () {} pessoa.prototype.name = "xxyh"; pessoa.prototype.age = "20"; Pessoa.Prototype.job = "Programmer"; Person.prototype.sayname = function () {alert (this.name);}; var) = novo (); "oooo"; alerta (pessoa1.name); // alerta "oooo" (Person2.Name); // "xxyh" excluir Person1.name; alert (Person1.name); // "xxyh"HasOwnProperty () pode detectar se existe uma propriedade em uma instância ou em um protótipo.
function pessoa () {} pessoa.prototype.name = "xxyh"; pessoa.prototype.age = "20"; Pessoa.Prototype.job = "Programmer"; Person.prototype.SayName = function () {alert (this.name);}; var pessoa1 = nova pessoa () Pessoa (); alerta (Person1.HasownProperty ("Nome")); // falseperson1.name = "oooo"; alert (Person1.HasownProperty ("nome")); // verdadeiroA figura a seguir mostra a relação entre implementação e protótipo em diferentes situações:
3.2 Protótipo e no operador
Como usar o operador In: use-o sozinho, em um loop for-in. Quando usado sozinho, o operador no IN retorna true ao acessar uma determinada propriedade através do objeto , se existe na instância ou no protótipo.
function pessoa () {} pessoa.prototype.name = "xxyh"; pessoa.prototype.age = "20"; Pessoa.Prototype.job = "Programmer"; Person.prototype.Sayname = function () {alert (this.name);}; var pessoa1 = nova (); // Trueperson1.name = "oooo"; alert ("nome" em pessoa1); // verdadeiroCombinado com o recurso anterior HASOWNPROPERTY (), pode -se determinar que uma propriedade é uma propriedade no protótipo ou uma propriedade na instância. Se o operador in retornar true e hasownProperty retornar false, a propriedade será uma propriedade no protótipo.
função hasprototypeProperty (objeto, nome) {return! Object.HasownProperty (nome) && (nome em objeto);}Em seguida, vamos dar uma olhada no uso do hasprototypeProperty ():
function pessoa () {} pessoa.prototype.name = "xxyh"; pessoa.prototype.age = "20"; pessoa.prototype.JOB = "Programmer"; Person.Prototype.SayName = function () {alert (this.name);}}; var = nova pessoa (); alert (); // Trueperson.name = "oooo"; alert (hasprototypeProperty (Pessoa, "nome")); // falseAo usar o loop for-in, todas as propriedades enumeráveis que podem ser acessadas através do objeto, incluindo propriedades na instância e propriedades no protótipo. Os atributos da instância que bloqueiam os dados não inocentes no protótipo (ou seja, atributos marcados como falsos por [[enumerável]]) também serão devolvidos em for-in, porque, de acordo com os regulamentos, todos os atributos definidos pelos desenvolvedores são enumeráveis.
Para obter todas as propriedades de instância enumeráveis em um objeto, você pode usar o método object.keys ().
function Person() {}Person.prototype.name = "xxyh";Person.prototype.age = "20";Person.prototype.job = "programmer";Person.prototype.sayName = function () { alert(this.name);};var keys = Object.keys(Person.prototype);alert(keys); // nome, idade, trabalho, SayNamevar p1 = new Person (); p1.name = "ooooo"; p1.age = 15; var p1_keys = object.keys (p1); alert (p1_keys); // nome, idadeSe você precisar obter todas as propriedades da instância, poderá usar o método Object.TetownPropertyNames ()
var keys = object.GetownPropertyNames (Person.prototype); alert (chaves); // "Construtor, nome, idade, trabalho, sayname"
3.3 Sintaxe de protótipo mais simples
Para otimizar a entrada, substitua o objeto de protótipo integrado por um objeto literal contendo todas as propriedades e métodos.
function Person () {} Person.prototype = {Nome: "XXYH", Idade: 18, Job: "Programador", SayName: function () {alert (this.name); }};O acima define o PERSON.Prototype para igual a um novo objeto criado na forma literal do objeto. O resultado é o mesmo, mas o atributo construtor não está mais apontando para a pessoa.
O resultado correto pode ser retornado através da instância, mas o construtor não pode determinar o tipo de objeto:
var boy = nova pessoa (); alerta (objeto de menino); // Truealert (pessoa do garoto de pessoa); // Truealert (Boy.Constructor == Pessoa); // FalsEalert (Boy.Constructor == Object); // verdadeiro
O valor do construtor pode ser definido das seguintes maneiras:
function Person () {} Person.prototype = {construtor: pessoa, nome: "xxyh", idade: 18, trabalho: "programador", SayName: function () {alert (this.name); }};3.4 Dinamicidade das cadeias de protótipo
Como o processo de encontrar valores em um protótipo é uma pesquisa, quaisquer modificações feitas no objeto de protótipo são refletidas na instância. Mas se todo o objeto de protótipo for reescrito, o resultado será diferente. Ao chamar o construtor, um ponteiro [[protótipo]] para o protótipo original é adicionado à instância e a modificação do protótipo para outro objeto é equivalente a cortar a conexão entre o construtor e o protótipo original. O ponteiro na instância aponta apenas para o protótipo, não para o construtor.
function pessoa () {} var boy = new Pessoa (); Person.prototype = {construtor: pessoa, nome: "xxyh", idade: 29, trabalho: "programador", sayname: function () {alert (this.name); }}; boy.sayName (); // erroO processo específico é o seguinte:
Como pode ser visto de cima, reescrever objetos de protótipo corta a conexão entre os protótipos existentes e quaisquer instâncias de objetos anteriormente existentes; Eles se referem ao protótipo original.
3.5 Protótipo de objeto nativo
Todos os tipos de referência nativos definem métodos no protótipo do construtor. Através do protótipo do objeto nativo, não apenas o método padrão pode ser obtido, mas também pode ser definido um novo método.
String.prototype.startswith = function (text) {return this.indexof (text) == 0;}; var msg = "bom dia"; alerta (msg.startswith ("bom")); // verdadeiro3.6 Problemas com objetos de protótipo
Existem dois problemas com o padrão de protótipo:
• Tudo o mesmo valor de atributo por padrão.
• Todos os atributos no protótipo são compartilhados pela instância
Vamos ver um exemplo abaixo:
function pessoa () {} pessoa.prototype = {construtor: pessoa, nome: "xxyh", idade: 18, trabalho: "programador", amigos: ["zhang san", "li si"], sayname: function () {alert (this.name); }}; var p1 = new Person (); var p2 = new Person (); P1.friends.push ("Wang Wu"); Alert (P1.friends); // Zhang San, Li Si, Wang Wu Alert (p2.friends); // Zhang San, Li Si, Wang Wu Alert (P1.friends == p2.friends); // verdadeiroUm item foi adicionado acima através do P1.Friends. Como a matriz de amigos existe pessoalmente. Prototipo, também se reflete em P2.Friends. No entanto, as instâncias geralmente têm todos os seus próprios atributos.
Use o modo construtor e o modo de protótipo em combinação
O modo construtor é usado para definir propriedades de instância e o modo de protótipo é usado para definir métodos e propriedades compartilhadas. Dessa forma, cada instância terá sua própria cópia dos atributos da instância, mas, ao mesmo tempo, compartilhará uma referência ao método.
função pessoa (nome, idade, trabalho) {this.name = name; this.age = idade; this.Job = Job; this.friends = ["zhang san", "li si"];} pessoa.prototype = {construtor: pessoa, SayName: function () {alert (this.name); }} var p1 = nova pessoa ("xiao xiao yihan", 18, "programador"); var p2 = nova pessoa ("kuiba", 10, "monster hunt"); p1.friends.push ("wang wu"); alert (p1.friends); // Zhang San, Li Si, alerta de Wang Wu (p2.friends); // Zhang San, Li Si Alert (P1.friends == p2.friends); // FalsEalSealert (P1.SayName == P2.SayName); // verdadeiroNo exemplo acima, as propriedades da instância são definidas no construtor, enquanto o construtor de propriedades compartilhadas e o método SayName () são definidos no protótipo. A modificação de P1.friends não afetará os resultados de P2.Friends.
Modo de protótipo dinâmico
O padrão de protótipo dinâmico encapsula todas as informações no construtor e, ao inicializar o protótipo no construtor, mantém a vantagem de usar o construtor e o protótipo. Ou seja, é possível determinar se o protótipo precisa ser inicializado, verificando se um método que deve existir é eficaz.
função pessoa (nome, idade, trabalho) {// propriedade this.name = name; this.age = idade; this.Job = Job; // método if (typeof this.sayName! = "Function") {Person.prototype.sayName = function () {alert (this.name); }}}Isso só será adicionado ao protótipo quando o método SayName () não existir e só será executado quando o construtor for chamado pela primeira vez.
Padrão de construtor parasitário
A idéia desse padrão é criar uma função cuja função é encapsular o código que cria o objeto e depois retornar o objeto recém -criado.
função pessoa (nome, idade) {var obj = new Object (); obj.name = nome; obj.age = idade; obj.sayName = function () {alert (this.name); } retornar obj;} var boy = nova pessoa ("xxyh", 19, "programador"); boy.sayname ();Deve -se notar: Antes de tudo, o objeto retornado não tem relação com o construtor ou os atributos do protótipo do construtor; O objeto retornado pelo construtor não é diferente do objeto criado fora do construtor. A instância do operador não pode ser confiada para determinar o tipo de objeto.
Padrão de construtor estável
Um objeto seguro refere -se a um objeto que não possui atributos públicos e seus métodos não se referem a isso. Os construtores estáveis seguem um padrão semelhante aos construtores parasitas, mas existem duas diferenças:
• O método de instância do objeto recém -criado não se refere a isso;
• Construtor não é chamado usando o novo operador
Reescreva o construtor da pessoa da seguinte forma:
função pessoa (nome, idade, trabalho) {var obj = new Object (); obj.sayname = function () {alert (nome); }; retornar obj;} função pessoa (nome, idade, trabalho) {var obj = new Object (); obj.sayname = function () {alert (nome); }; retornar obj;}O artigo acima fala brevemente sobre a criação de objetos JavaScript é todo o conteúdo que compartilho com você. Espero que possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.