A cadeia de protótipos é um pouco confusa de entender, e há muitas informações on -line. Toda vez que não consigo dormir à noite, sempre gosto de encontrar algumas redes de protótipos e fechamentos on -line para ler, o que é muito eficaz.
Não se preocupe com esses muitos termos, isso realmente não o ajudará, exceto para fazer seu cérebro torcer. Basta olhar para a cadeia de protótipos de maneira simples e aproximada e pensar em coisas que não têm nada a ver com o código, como seres humanos, demônios e homens de transsexto.
1) As pessoas nascem por seres humanos e os monstros nascem por demônios. Humanos e demônios são casos de objetos, enquanto humanos e demônios são protótipos. Um protótipo também é um objeto, chamado de protótipo.
2) A mãe de uma pessoa e seu pai podem dar à luz um monte de bebês, e uma mãe demoníaca e seu pai podem dar à luz um monte de bebês. A esposa de um homem e um homem podem dar à luz um monte de bebês. Um homem é um construtor, comumente conhecido como homem.
3) As pessoas podem gravar informações sobre sexo, para que as pessoas possam encontrar informações sobre sexo através do sexo, ou seja, elas podem encontrar o construtor através de objetos de protótipo.
4) As pessoas podem dar à luz muitos bebês em suas mães, mas esses bebês têm apenas uma mãe, que é a singularidade do protótipo.
5) As pessoas também nascem por pessoas, encontram pessoas através de pessoas e depois encontram pessoas através das pessoas ... Esse relacionamento é chamado de cadeia de protótipo.
6) A cadeia do protótipo não é infinita. Quando você continua olhando para as pessoas, descobrirá que as pessoas estão fodendo ... não são seres humanos, ou seja, a cadeia de protótipos finalmente aponta para NULL.
7) As pessoas nascidas com uma mãe se parecem com pessoas, e monstros nascidos com uma mãe serão feios. Isso é chamado de herança.
8) Você herdou a cor da pele de sua mãe, sua mãe herdou a cor da pele de sua mãe, sua mãe ..., essa é a herança da cadeia de protótipo.
9) Se você não tem uma casa, então sua casa se refere à casa de sua mãe; Se sua mãe não tem uma casa, então sua casa se refere à casa de sua mãe ... Esta é a busca ascendente da cadeia de protótipos.
10) Você herdará a aparência de sua mãe, mas também pode pintar seu cabelo, shampoo, cortar e soprar, ou seja, os atributos do objeto podem ser personalizados e substituirá os atributos herdados.
11) Embora você tenha lavado, cortado, soprado e tingido pelos cabelos amarelos, você não pode mudar a aparência de sua mãe. O irmão e a irmã mais novos nascidos de sua mãe não têm nada a ver com a lavagem de cabelos amarelos, cortados e soprados cabelos amarelos, ou seja, a instância do objeto não pode alterar as propriedades do protótipo.
12) Mas se sua casa é queimada por você, significa que sua mãe e seus irmãos estão queimados, e este é o compartilhamento de atributos de protótipo.
13) O apelido de sua mãe é Azhen, e a tia de seu vizinho chama você Azhener, mas depois que o cabelo de sua mãe passou de Piaorou para o rei do leão dourado, a tia ao lado mudou suas palavras e o chamou de príncipe de leão dourado. Isso é chamado de natureza dinâmica do protótipo.
14) Sua mãe adora beleza e foi à Coréia para cirurgia plástica. Ela não conseguia nem reconhecer sua mãe. Mesmo que os cabelos de sua mãe tenham mudado de volta para a suavidade, a vizinha ao lado ainda o chamou de príncipe de leão dourado. Como ninguém reconheceu sua mãe, sua mãe voltou à fábrica após a cirurgia plástica. Esta é a reescrita geral do protótipo.
Caramba! Você é o suficiente! Não bb! Mostre -me o código!
função pessoa (nome) {this.name = name; } função mãe () {} mãe.prototype = {// Prototipo da mãe idade: 18, casa: ['beijing', 'shanghai']}; pessoa.prototype = nova mãe (); // O protótipo da pessoa é mãe // Use a ferramenta de depuração do Chrome para visualizar o protótipo, fornecendo a interface __proto__ para visualizar o protótipo var p1 = new pessoa ('jack'); // P1: 'Jack'; __proto __: 18, ['Pequim', 'shanghai'] var p2 = nova pessoa ('mark'); // P2: 'Mark'; __proto __: 18, ['Pequim', 'shanghai'] p1.age = 20; /* A instância não pode alterar o atributo de valor básico do protótipo, assim como você lava, corta, sopra e tinge o cabelo amarelo não tem nada a ver com sua mãe* A operação comum de adicionar um atributo de idade na instância P1 não tem nada a ver com o protótipo. O mesmo que var o {}; O.age = 20. * P1: Há uma idade de atributo adicional abaixo e __proto__ é o mesmo que mãe.prototipo, idade = 18. * P2: apenas o nome do atributo, __proto__ é o mesmo que mãe.prototipo*/p1.home [0] = 'Shenzhen'; /* O compartilhamento de atributos do tipo de referência no protótipo é como você queimar sua casa, está queimando a casa de toda a sua família* Isso é um passe, vamos incomodá -lo com cuidado? * P1: 'Jack', 20; __Proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 18, ['Shenzhen', 'shanghai']*/p1.home = ['Hangzhou', 'Guangzhou']; /* De fato, a mesma operação que P1.age = 20. Mudar para esse entendimento: var o {}; O.House = ['Big', 'House']* P1: 'Jack', 20, ['Hangzhou', 'Guangzhou']; __Proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 18, ['Shenzhen', 'shanghai']*/exclua P1.age; /* Após a exclusão dos atributos personalizados, o valor do protótipo originalmente substituído será reexpectado. Este é o mecanismo de pesquisa ascendente, então há a seguinte dinâmica* P1: 'Jack', ['Hangzhou', 'Guangzhou']; __Proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __Proto __: 18, ['Shenzhen', 'shanghai']*/pessoa.prototype.lastName = 'Jin'; /* Reescreva o protótipo e reaja dinamicamente à instância. Assim como sua mãe se tornou uma pessoa moderna, os vizinhos dizem que você é filho de uma mulher moderna quando mencionam* observe que estamos reescrevendo o protótipo da pessoa aqui, que é adicionar um atributo Lastname à mãe, que é equivalente à mãe. Se você alterar níveis diferentes, os efeitos geralmente serão muito diferentes. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'shanghai']* P2: 'Mark'; __Proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai']*/Person.prototype = {Age: 28, endereço: {country: 'EUA', cidade: 'washington'}}; var p3 = nova pessoa ('obama'); /* Reescreva o protótipo! Nesse momento, o protótipo da pessoa havia se tornado completamente um novo objeto, o que significa que essa pessoa havia mudado sua mãe. * Para entender assim: var a = 10; b = a; a = 20; c = a. Portanto, B permanece inalterado e se torna C, então o P3 muda e não tem nada a ver com a mãe. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'shanghai']* P2: 'Mark'; __Proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai']* P3: 'Obama'; __ Proto__: 28 {country: 'USA', Cidade: 'Washington'}*/mãe.ProType.NoType. Assim como sua mãe se tornou uma nova tendência, os vizinhos dizem que você é realmente uma avó da moda*, observe que estamos reescrevendo a mãe. Prototipo aqui, o P1P2 mudará, mas o P3 acima não tem nada a ver com a mãe e isso não o afetará. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'shanghai'], 9527* P2: 'Mark'; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai'], 9527* p3: 'Obama'; __Proto__: 28 {country: 'USA', cidade: 'Washington'}*/Mother.prototype = {Car: 2, Hobby: ['Run', 'Walk']}; var P4 = nova pessoa ('Tony');/* Reescreva o protótipo do protótipo! Neste momento, o protótipo da mãe se tornou completamente um novo objeto! * Como a pessoa e a mãe foram desconectadas de cima, a mudança da mãe não afetará mais a pessoa. * P4: 'Tony'; __ Proto__: 28 {country: 'USA', City: 'Washington'}*/Person.prototype = new Mother (); // liga var novamente p5 = nova pessoa ('luffy'); // Se você precisar aplicar essas alterações no momento, deve re-amarrar o protótipo da pessoa para a mãe // p5: 'luffy'; __ proto__: 2, ['run', 'walk'] p1 .__ proto __. __ proto __. __to __to __to __ton __ton __ton, null null null, proto-null, proto-null, null null null e protro __tone __ton __, proto, null null, null null, protron __ton, null null e null null e proto-n. Mãe .__ Proto __.__ Proto __.__ Proto__ // NULL, você acha que o ponto final da cadeia de protótipos não é nulo?Você pode basicamente entender depois de lê -lo?
Agora vamos falar sobre a diferença entre P1.age = 20, p1.home = ['Hangzhou', 'Guangzhou'] e P1.home [0] = 'Shenzhen'. p1.home [0] = 'Shenzhen'; Para resumir, é uma forma como p1.Object.method, p1.object.property.
p1.age = 20; p1.home = ['Hangzhou', 'Guangzhou']; Essas duas frases são fáceis de entender. Esqueça o protótipo primeiro e pense em como adicionamos atributos a um objeto comum:
var obj = new Object (); obj.name = 'xxx'; obj.num = [100, 200];
Você entende dessa maneira? É o mesmo.
Então, por que P1.Home [0] = 'Shenzhen' cria uma propriedade de matriz doméstica sob P1 e depois define sua primeira posição para 'Shenzhen'? Vamos esquecer isso primeiro, pense no objeto OBJ acima. Se for escrito assim: var obj.name = 'xxx', obj.num = [100, 200], você pode obter o resultado que deseja? Obviamente, você não receberá nada, exceto por um erro. Como o OBJ ainda não foi definido, como você pode adicionar algo a ele? Da mesma forma, a casa em P1.home [0] não é definida em P1, por isso é impossível definir diretamente o lar [0]. Se você deseja criar uma matriz doméstica sob P1, é claro que está escrita assim:
p1.home = []; p1.home [0] = 'Shenzhen';
Não é esse o método mais usado?
A razão pela qual P1.home [0] = 'Shenzhen' não relata diretamente um erro é porque existe um mecanismo de pesquisa na cadeia de protótipo. Quando entramos em P1.Object, o mecanismo de pesquisa da cadeia de protótipos é procurar o valor correspondente na instância primeiro. Se não puder ser encontrado, ele será pesquisado no protótipo. Se não puder ser encontrado, ele pesquisará no nível anterior da cadeia de protótipos ... chegará ao final da cadeia de protótipos, ou seja, se ainda não foi encontrado, ele retornará um indefinido. Quando entramos em P1.home [0], o mesmo mecanismo de pesquisa também é verdadeiro. Primeira pesquisa P1 para ver se há algum atributo e métodos chamados de casa e, em seguida, pesquise passo a passo. Finalmente, o encontramos no protótipo da mãe, então modificar é equivalente a modificar o protótipo da mãe.
Em resumo: p1.home [0] = 'shenzhen' é equivalente a mãe.prototype.home [0] = 'Shenzhen'.
A partir da análise acima, podemos ver que o principal problema da herança da cadeia de protótipos está no compartilhamento de atributos. Muitas vezes, queremos compartilhar apenas métodos, mas não atributos. Idealmente, cada instância deve ter atributos independentes. Portanto, existem duas maneiras de melhorar a herança do protótipo:
1) Herança combinada
função mãe (idade) {this.age = idade; this.hobby = ['Running', 'Football']} Mother.prototype.showage = function () {console.log (this.age); }; função pessoa (nome, idade) {mãe.call (isto, idade); // Segunda execução this.name = nome; } Pessoa.prototype = new Mother (); // Primeira execução Person.prototype.Constructor = Pessoa; Pessoa.Prototype.showname = function () {Console.log (this.name);} var p1 = new Person ('Jack', 20); p1.hobby.push ('basquete'); // P1: 'Jack'; __Proto __: 20, ['Running', 'Football'] var P2 = New Pessoa ('Mark', 18); // P2: 'Mark'; __proto __: 18, ['Running', 'Football']O resultado é roxo:
Quando a primeira execução é realizada aqui, você recebe Person.prototype.age = indefinido, PERSON.Prototype.hobby = ['Running', 'Football']. A segunda execução é que var p1 = nova pessoa ('Jack', 20) e você obtém P1.age = 20, P1.Hobby = ['Running', 'Football']. Depois de empurrar, torna -se P1.HOBBY = ['Running', 'Football', 'Basketball']. De fato, é relativamente simples entender as mudanças disso. Você pode obter esse resultado simplesmente substituindo isso. Se você acha que é um pouco confuso entender, tente jogar fora os conceitos em sua mente e execute o código de cima para baixo como navegador. Vai sair?
Ao executar o protótipo construtor mãe () pela segunda vez, copiamos uma cópia das propriedades do protótipo na instância do objeto, para que possamos separar e separar as propriedades do protótipo. Se você tiver cuidado, descobrirá que a primeira vez que chamamos de Mother (), parece que não há utilidade. Como não podemos chamá -lo? Sim, existe a seguinte herança de combinação parasitária.
2) Herança de combinação parasitária
função objeto (o) {função f () {} f.prototype = o; retorna novo f ();} função herança prototótipo (pessoa, mãe) {var prototype = objeto (mãe.prototype); prototype.Constructor = Pessoa; Pessoa.Prototype = protótipo; } função mãe (idade) {this.age = idade; this.hobby = ['Running', 'Football']} Mother.prototype.showage = function () {console.log (this.age); }; função pessoa (nome, idade) {mãe.call (isto, idade); this.name = nome; } herançaprotótipo (pessoa, mãe); PERSON.PROTOTYPE.SHOWNAME = function () {console.log (this.name);} var p1 = new Person ('Jack', 20); p1.hobby.push ('basquete'); // p1: 'jack'; __Proto __: 20, ['Running', 'Football'] var P2 = New Pessoa ('Mark', 18); // P2: 'Mark'; __proto __: 18, ['Running', 'Football']O resultado é roxo:
Não há mais atributos de idade e hobby no protótipo, existem apenas dois métodos, que são exatamente o resultado que queremos!
O ponto -chave está no objeto (O), onde um objeto temporário é emprestado aqui para evitar inteligentemente chamar a nova mãe () e, em seguida, retornar uma nova instância de objeto com o protótipo O, preenchendo assim a configuração da cadeia de protótipo. É muito confuso, certo? Isso porque não podemos definir diretamente a pessoa.prototype = Mother.prototype.
resumo
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Dito tanto, na verdade existe apenas um núcleo: compartilhamento de atributos e controle independente. Quando a instância do seu objeto precisa de atributos independentes, a essência de todas as práticas é criar atributos na instância do objeto. Se você não pensa muito, pode definir diretamente os atributos independentes necessários pessoalmente para substituir as propriedades do protótipo. Em suma, ao usar a herança do protótipo, você deve prestar atenção especial aos atributos no protótipo, porque são todas as existências que afetam todo o corpo.
Abaixo está uma lista simples de vários métodos para criar objetos em JS. O método mais usado agora é o modo de combinação. Os alunos familiares podem pular para o final do artigo e gostar.
1) Modo original
// 1. Modo original, modo de objeto literal var pessoa = {nome: 'jack', idade: 18, SayName: function () {alert (this.name); }}; // 1. Modo original, modo de construtor de objeto var pessoa = new Object (); pessoa.name = 'jack'; pessoa.age = 18; pessoa.SayName = function () {alert (this.name);};Obviamente, quando queremos criar lotes de pessoa1, pessoa2 ..., temos que digitar muito código todas as vezes, e até os copypasters seniores não conseguem suportar! Depois, há um modelo de fábrica de produção em massa.
2) Modelo de fábrica
// 2. Modo de fábrica, defina uma função para criar função de objeto createPerson (nome, idade) {var temp = new Object (); pessoa.name = nome; pessoa.age = idade; pessoa. }O modo de fábrica é a produção em massa e você pode entrar no modo de fabricação de homens com uma chamada simples (papapapa ...). Você pode criar um monte de bebês especificando seu nome e idade e libertar suas mãos. No entanto, como é operado em uma fábrica, você não pode identificar que tipo de objeto é, seja um humano ou um cão (a instância do teste é objeto). Além disso, toda vez que você cria um humano, você precisa criar um objeto temporário independente, o código é inchado e a borboleta é elegante.
3) Construtor
// 3. Modo construtor, defina uma função construtora para a pessoa da função do objeto (nome, idade) {this.name = name; this.age = idade; this.sayname = function () {alert (this.name);}; } var p1 = new Pessoa ('Jack', 18); // Crie uma pessoa do objeto P1 ('Jack', 18); // Os métodos de atributo são fornecidos ao objeto da janela, Window.Name = 'Jack', Window.sayName () será lançado com tomadaO construtor é semelhante aos construtores de classes em C ++ e Java e é fácil de entender. Além disso, a pessoa pode ser usada como reconhecimento de tipo (a instância do teste é pessoa e objeto). No entanto, todas as instâncias ainda são independentes e métodos de diferentes instâncias são realmente funções diferentes. Esqueci a palavra função aqui, basta tratar o SayName como um objeto e entenda. Ou seja, o Sayname de Zhang San e o Sayname de Li Si têm existências diferentes, mas obviamente o que esperamos é compartilhar um SayName para salvar a memória.
4) Modo de protótipo
// 4. Modo de protótipo, defina diretamente o protótipo atributo function Person () {} Person.prototype.name = 'Jack'; Person.Prototype.age = 18; Person.prototype.SayName = function () {alert (this.name); }; // 4. Protótipo, método de definição literal Person () {} Person.prototype = {Nome: 'Jack', idade: 18, SayName: function () {alert (this.name); }}; var p1 = new Person (); // nome = 'Jack'var P2 = new Person (); // nome = 'jack'O que precisa ser observado aqui é o compartilhamento de atributos e métodos de protótipo, ou seja, todas as instâncias se referem apenas aos métodos de atributo no protótipo, e as alterações geradas em qualquer lugar causarão alterações em outras instâncias.
5) Modo misto (construção + protótipo)
// 5. Modo de combinação de construção de protótipo, pessoa da função (nome, idade) {this.name = name; this.age = Age;} Person.prototype = {hobby: ['Running', 'Football']; SayName: function () {alert (this.name); }, Sayage: function () {alert (this.age); }}; var p1 = nova pessoa ('Jack', 20); // P1: 'Jack', 20; __Proto__: ['Running', 'Football'], Sayname, Sayagevar P2 = New Pessoa ('Mark', 18); // P1: 'Mark', 18; __ Proto__: ['Running', 'Football'], Sayname, SayageA abordagem é colocar os métodos de propriedade que precisam ser independentes no construtor, e as peças que podem ser compartilhadas são colocadas no protótipo. Isso pode maximizar a economia da memória, mantendo a independência das instâncias de objetos.