Um. Dois protótipos
Muitas pessoas sabem que JavaScript é uma herança de protótipo. Cada construtor possui um membro do protótipo, através do qual a herança JavaScript pode ser bonita.
De fato, esse atributo sozinho não pode concluir a herança do JavaScript.
Não vou dizer muito sobre o protótipo que usamos no código. Você pode verificar as informações.
Outro membro do protótipo invisível.
Cada instância possui um atributo de protótipo apontando para o protótipo. Esse atributo não pode ser acessado e, é claro, não pode ser modificado, porque essa é a base para manter a herança JavaScript.
A cópia do código é a seguinte:
// Declaração do construtor
função guoyansi () {}
função guoyansiex () {}
// Herança de protótipo
Guoyansiex.prototype = new guoyansi ();
// Crie um objeto
var g1 = novo guoyansiex ();
var g2 = novo guoyansiex ();
Os objetos no código acima podem ser explicados pela figura a seguir
2. Manutenção do protótipo
Uma instância gerada por um construtor cujo atributo construtor sempre aponta para o construtor. Pensaremos que a afirmação está correta por enquanto.
A cópia do código é a seguinte:
função guoyansi () {}
var obj1 = new guoyansi ();
console.log (obj1.Constructor === Guoyansi); // true
De fato, o próprio construtor não possui o atributo construtor, então de onde vem esse atributo?
A resposta é: do protótipo.
Portanto, as seguintes conclusões são tiradas
A cópia do código é a seguinte: obj1.Constructor === guoyansi.prototype.constructor === Guoyansi
Como podemos encontrar o construtor através do construtor, podemos melhorar ainda mais o diagrama acima.
A cópia do código é a seguinte:
função guoyansiex () {}
Guoyansiex.prototype = new guoyansi ();
console.log (guoyansiex.constructor === Guoyansiex) // false
De acordo com a foto acima, o resultado acima deve ser verdadeiro, mas por que é falso?
Agora faça uma análise.
O protótipo de Guoyansiex foi reescrito pela instância de Guoyansi, de modo que o construtor no protótipo de Guoyansiex é naturalmente também um exemplo de Guoyansi.
O construtor na instância de Guoyansi vem do guoyansi.prototype. No entanto, Guoyansi.Prototype não foi reescrito.
Portanto, o construtor de Guoyansi.Prototype aponta para Guoyansi (construtor);
Com base na análise acima, tiramos as seguintes conclusões
A cópia do código é a seguinte: guoyansiex.constructor === Guoyansi.Constructor === Guoyansi;
Se os requisitos de diretiva do construtor forem muito precisos durante o processo de desenvolvimento, o processamento a seguir poderá ser feito.
A cópia do código é a seguinte:
/** Método 1: **/
função guoyansi () {}
função guoyansiex () {}
Guoyansiex.prototype = new guoyansi ();
Guoyansiex.prototype.constructor = guoyansiex; // Redefinir ponteiro do construtor.
A cópia do código é a seguinte:
/**
Método 2
**/
função guoyansi () {}
função guoyansiex () {
this.Constructor = argumentos.callee;
}
Guoyansiex.prototype = new guoyansi ();
A cópia do código é a seguinte:
/**
Método 3
**/
função guoyansi () {}
função guoyansiex () {
this.Constructor = Guoyansiex;
}
Guoyansiex.prototype = new guoyansi ();
3. Qual é o uso de um protótipo invisível?
Podemos operar a cadeia de protótipo visível para concluir nossa herança, para que não possamos ver e operar essa cadeia de protótipo invisível. Qual é o uso disso?
Há um recurso na herança orientada a objetos: similaridade. As subclasses têm semelhanças com as classes dos pais. Portanto, em subclasses, você não pode usar excluir para excluir membros herdados das classes dos pais. Ou seja, as subclasses devem ter as características das classes pais.
Para manter esse recurso, o JavaScript gera uma propriedade de protótipo invisível dentro do objeto e não permite que o usuário o acesse. Dessa forma, o usuário pode modificar o construtor para qualquer finalidade,
Não destruirá as características da classe infantil com a classe pai.
Em resumo: os protótipos internos são exigidos pelo mecanismo de herança do protótipo de JavaScript, enquanto protótipos externos são necessários pelos usuários para implementar a herança.
4. __Proto__ no motor Firefox Spidermonkey
Ainda este código.
A cópia do código é a seguinte:
função guoyansi () {}
Guoyansi.prototype.age = 24;
função guoyansiex () {}
var obj1 = new guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.prototype.constructor = guoyansiex; // Redefinir ponteiro do construtor.
var obj2 = new guoyansiex ();
Agora, quero acessar a idade das propriedades do protótipo da classe dos pais guoyansi a partir do OBJ.
Esta é a ideia.
Etapa 1: obj2 ====> obj2.Constructor.prototype
Parte 2: obj2.constructor.prototype ===> guoyansiex.prototype;
Parte 3: guoyansiex.prototype ===> obj1;
Parte 4: Obj1.Constructor ====> Guoyansi
Parte 5: guoyansi.prototype.age
Escreva assim: console.log (obj2.constructor.prototype.constructor.prototype.age) // 24;
O resultado final é 24.
O resultado final é 24. Ele pode ser executado normalmente, mas em muitos livros, diz que depois que o construtor é modificado, o nível não pode encontrar o protótipo na classe pai. Não sei o que está acontecendo.
Chega de um atributo mais conciso no Firefox._proto_
Por padrão, Spidermonkey adiciona um atributo chamado _proto_ a qualquer objeto criado, que aponta para o protótipo usado pelo construtor.
De fato, é a cadeia de protótipo invisível que mencionamos acima, mas é apenas uma divulgação disfarçada neste local.
Você pode acessar a idade dessa maneira
console.log (obj2 .__ Proto __.__ Proto __. Idade); // 24
Isso realmente acessa com sucesso o atributo protótipo da classe pai, mas esse atributo é aplicável apenas ao Firefox e haverá erros em outros navegadores.
No E5, o objeto é estendido ao object.getProTypeOf () e você pode acessar todos os protótipos da classe pai.
A cópia do código é a seguinte:
função guoyansi () {}
Guoyansi.prototype.age = 24;
função guoyansiex () {}
var obj1 = new guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.prototype.constructor = guoyansiex; // Redefinir ponteiro do construtor.
var obj2 = new guoyansiex ();
var proto = object.getProTypeOf (obj2);
while (proto) {
console.log (proto.constructor);
proto = object.getPrototypeOf (proto);
}
console.log ("protótipo do objeto"+proto);
O resultado é: guoyansiex
Guoyansi
Objeto
Protótipo nulo para objeto
Pessoalmente, acho que eles devem ser considerados uma das essências do JavaScript orientado a objetos. Consulte -o e use -o em seu próprio projeto de acordo com suas necessidades.