Cada objeto no JavaScript possui um protótipo de propriedade interno. A explicação da propriedade do protótipo de um objeto no JavaScript é: retornar uma referência ao protótipo do tipo de objeto. Isso significa que o atributo do protótipo mantém uma referência a outro objeto JavaScript, que atua como pai do objeto atual.
A cópia do código é a seguinte:
A.Prototype = new B ();
A compreensão do protótipo não deve ser confundido com a herança. O protótipo de A é uma instância de B. Pode -se entender que um clonado todos os métodos e propriedades em B. A pode usar os métodos e propriedades de B. O que é enfatizado aqui é a clonagem e não a herança. Isso pode acontecer: o protótipo de A é uma instância de B, e o protótipo de B também é uma instância de A.
Continue analisando a seguinte análise:
Variáveis e funções privadas
Se as variáveis e funções definidas dentro da função não forem fornecidas externamente, elas não poderão ser acessadas externamente, ou seja, as variáveis e funções privadas da função.
A cópia do código é a seguinte:
<script type = "text/javascript">
caixa de função () {
var color = "azul"; // variável privada
var fn = function () // função privada
{
}
}
</script>
Dessa forma, as variáveis de cor e FN não podem ser acessadas fora da caixa de objeto de função, e elas se tornam privadas:
A cópia do código é a seguinte:
var obj = new Box ();
alerta (obj.color); // pop-up indefinido
alerta (obj.fn); // o mesmo que acima
Variáveis e funções estáticas
Quando uma função é definida, os atributos e funções adicionados a ela ainda são acessíveis através do próprio objeto, mas seus exemplos não podem ser acessados. Tais variáveis e funções são chamadas variáveis estáticas e funções estáticas, respectivamente.
A cópia do código é a seguinte:
<script type = "text/javascript">
função obj () {};
Obj.num = 72; // variável estática
Obj.fn = function () // função estática
{
}
alerta (obj.num); // 72
alerta (tipo de obj.fn) // função
var t = novo obj ();
alerta (t.name); // indefinido
alerta (tipo de t.fn); // indefinido
</script>
Variáveis e funções de instância
Na programação orientada a objetos, além de algumas funções da biblioteca, ainda esperamos definir algumas propriedades e métodos ao mesmo tempo em que a definição de objeto, para que eles possam ser acessados após a instanciação e o JS também pode fazer isso.
A cópia do código é a seguinte:
<script type = "text/javascript">
caixa de função () {
this.a = []; // Variável de instância
this.fn = function () {// Método da instância
}
}
console.log (tipoof box.a); //indefinido
console.log (tipoof box.fn); //indefinido
var box = new Box ();
console.log (tipoof box.a); //objeto
console.log (tipoof box.fn); //função
</script>
Adicione novos métodos e propriedades às variáveis e métodos de instância
A cópia do código é a seguinte:
<script type = "text/javascript">
caixa de função () {
this.a = []; // Variável de instância
this.fn = function () {// Método da instância
}
}
var box1 = new Box ();
Box1.a.push (1);
Box1.fn = {};
console.log (Box1.a); // [1]
console.log (tipoof box1.fn); //objeto
var box2 = new Box ();
console.log (box2.a); // []
console.log (tipoof box2.fn); //função
</script>
A e FN foram modificados no Box1, mas não no Box2. Como matrizes e funções são objetos e são tipos de referência, isso significa que, embora as propriedades e os métodos no Box1 sejam os mesmos do Box2, eles não são uma referência, mas uma cópia das propriedades e métodos definidos pelo objeto da caixa.
Isso não tem nenhum problema com as propriedades, mas é um grande problema para os métodos, porque os métodos estão fazendo exatamente a mesma função, mas existem duas cópias. Se um objeto de função possui milhares e métodos de instância, cada instância deve manter uma cópia de milhares de métodos. Isso é obviamente não científico. O que posso fazer? O protótipo surgiu.
Conceitos básicos
Cada função que criamos possui uma propriedade de protótipo, que é um ponteiro para um objeto, e seu objetivo é conter propriedades e métodos que podem ser compartilhados por todas as instâncias de um tipo específico. Em seguida, o protótipo é o protótipo do objeto da instância do objeto criado chamando o construtor.
A vantagem de usar um protótipo é que ele permite que uma instância de objeto compartilhe as propriedades e métodos que ele contém. Ou seja, em vez de adicionar informações de objeto de definição ao construtor, você pode adicionar essas informações diretamente ao protótipo. O principal problema com o uso de construtores é que cada método precisa ser criado uma vez em cada instância.
No JavaScript, existem dois tipos de valores, valores originais e valores de objeto. Cada objeto possui um protótipo de propriedade interna, que geralmente chamamos de protótipo. O valor do protótipo pode ser um objeto ou nulo. Se seu valor for um objeto, o objeto também deve ter seu próprio protótipo. Isso forma uma cadeia linear, que chamamos de cadeia de protótipo.
significado
As funções podem ser usadas como construtores. Além disso, apenas a função possui um atributo de protótipo e pode ser acessado, mas a instância do objeto não possui esse atributo, existe apenas um atributo __proto__ inacessível interno. __proto__ é um elo misterioso no objeto para o protótipo relevante. De acordo com o padrão, __proto__ não é divulgado ao público, o que significa que é uma propriedade privada, mas o mecanismo do Firefox o expôs e se tornou uma propriedade comum, que podemos acessar e definir.
A cópia do código é a seguinte:
<script type = "text/javascript">
Var navegador = function () {};
Browser.prototype.run = function () {
alerta ("Sou Gecko, um núcleo do Firefox");
}
var Bro = new Browser ();
Bro.run ();
</script>
Quando chamamos o método Bro.Run (), como não existe esse método no irmão, ele o procurará em seu __proto__, ou seja, navegador.prototipo, para que o método run () seja finalmente executado. (Aqui, a letra capitalizada da função representa o construtor para distinguir funções ordinárias)
Ao chamar o construtor para criar uma instância, a instância conterá um ponteiro interno (__proto__) apontando para o protótipo do construtor. Essa conexão existe entre a instância e o protótipo do construtor, não entre a instância e o construtor.
A cópia do código é a seguinte:
<script type = "text/javascript">
Função Pessoa (nome) {// Função do construtor
this.name = nome;
}
Pessoa.prototype.printName = function () // Objeto de protótipo
{
alerta (this.name);
}
var pessoa1 = nova pessoa ('byron'); // instancia o objeto
console.log (Person1 .__ Proto __); // Pessoa
console.log (Person1.Constructor); // tente você mesmo para ver o que será
console.log (Person.prototype); // apontar para o protótipo Pessoa do objeto
var pessoa2 = nova pessoa ('Frank');
</script>
A Pessoa da Pessoa 1 contém o atributo de nome e gera automaticamente um atributo __proto__, que aponta para o protótipo da pessoa, e você pode acessar o método PrintName definido no protótipo, que provavelmente é assim:
Cada função JavaScript possui um atributo de protótipo, que se refere a um objeto, que é o objeto de protótipo. O objeto de protótipo está vazio ao inicializar. Podemos personalizar quaisquer propriedades e métodos nele. Esses métodos e propriedades serão herdados pelos objetos criados pelo construtor.
Então, agora o problema é. Qual é a relação entre construtor, instância e objeto de protótipo?
A diferença entre construtores, instâncias e objetos de protótipo
Uma instância é criada através de um construtor. Depois que uma instância é criada, ele possui o atributo construtor (apontando para a função do construtor) e o atributo __proto__ (apontando para o objeto protótipo).
Existe uma propriedade de protótipo no construtor, que é um ponteiro para seu objeto de protótipo.
Há também um ponteiro (propriedade construtora) dentro do protótipo objeto apontando para o construtor: PERSON.PROTOTYPE.CONSTUTOR = PESOL;
As instâncias podem acessar propriedades e métodos definidos no objeto de protótipo.
Aqui a pessoa1 e a pessoa2 são instâncias, e o protótipo são seus objetos de protótipo.
Outra castanha:
A cópia do código é a seguinte:
<script type = "text/javascript">
função animal (nome) // acumular construtor
{
this.name = name; // Definir propriedades do objeto
}
Animal.prototype.behavior = function () // Adicione método de comportamento ao protótipo do construtor da classe base
{
alerta ("este é um"+this.name);
}
var cão = novo animal ("cachorro"); // Crie um objeto de cachorro
var cat = novo animal ("gato"); // Crie um objeto CAT
Cachorro.BeHavior (); // Chame o método de comportamento diretamente através do objeto de cachorro
Cat.BeHavior (); // Saída "Este é um gato"
alerta (cachorro.BeHavior == Cat.BeHavior); // Uat True;
</script>
Pode ser visto nos resultados executando os resultados que os métodos definidos no protótipo do construtor podem realmente ser chamados diretamente através do objeto e o código é compartilhado. (Você pode tentar remover a propriedade do protótipo em animal.prototype.behavior para ver se ele ainda pode ser executado.) Aqui, o protótipo de propriedade aponta para o objeto animal.
Instância do objeto da matriz
Vejamos uma instância do objeto Array. Quando criamos a matriz de objeto1, o modelo de objeto real do Array1 no mecanismo JavaScript é o seguinte:
A cópia do código é a seguinte:
var Array1 = [1,2,3];
O objeto Array1 tem um valor de atributo de comprimento de 3, mas podemos adicionar elementos à matriz1 pelo seguinte método:
A cópia do código é a seguinte:
Array1.push (4);
O método push vem de um método que aponta para o objeto pelo membro __proto__ do Array1 (Array.prototye.push ()). É precisamente porque todos os objetos da matriz (criados através []) contêm um membro __proto__ apontando para o mesmo objeto de método com push, reverso, etc. (Array.prototype), que esses objetos de matriz podem usar push, reverso e outros métodos.
Instância do objeto de função
A cópia do código é a seguinte:
função base () {
this.id = "base"
}
A cópia do código é a seguinte:
var obj = new Base ();
Qual é o resultado desse código? O modelo de objeto que vemos no mecanismo JavaScript é:
O que exatamente o novo operador fez? Na verdade, era muito simples, apenas fez três coisas.
A cópia do código é a seguinte:
var obj = {};
obj .__ proto__ = base.prototipo;
Base.call (obj);
Cadeia de protótipo
Cadeia de protótipo: quando uma propriedade ou método é recuperado de um objeto, se o próprio objeto não tiver tal propriedade ou método, ele procurará o objeto de protótipo com o qual você se associar. Se não houver protótipo, ele procurará o antecessor do protótipo associado ao protótipo. Se não houver mais, continue pesquisando o objeto referenciado pelo prototype.prototype e assim por diante até que o protótipo ....... o protótipo seja indefinido (o protótipo do objeto é indefinido), formando assim a chamada "cadeia de protótipo".
A cópia do código é a seguinte:
<script type = "text/javascript">
forma de função () {
this.name = "shape";
this.toString = function () {
retornar este.name;
}
}
função twoshape () {
this.Name = "2 Shape";
}
Triângulo da função (lateral, altura) {
this.name = "Triangle";
this.side = lado;
this.Height = altura;
this.getarea = function () {
retornar this.side*this.Height/2;
}
}
Twoshape.prototype = new Shape ();
Triângulo.prototype = new Twoshape ();
</script>
Aqui, uma nova entidade é criada com a forma do construtor () e, em seguida, é usada para substituir o protótipo do objeto.
A cópia do código é a seguinte:
<script type = "text/javascript">
forma de função () {
this.name = "shape";
this.toString = function () {
retornar este.name;
}
}
função twoshape () {
this.Name = "2 Shape";
}
Triângulo da função (lateral, altura) {
this.name = "Triangle";
this.side = lado;
this.Height = altura;
this.getarea = function () {
retornar this.side*this.Height/2;
}
}
Twoshape.prototype = new Shape ();
Triângulo.prototype = new Twoshape ();
Twoshape.prototype.constructor = twoshape;
Triângulo.prototype.Constructor = Triangle;
var my = novo triângulo (5,10);
my.getarea ();
my.toString (); // Triângulo
my.Constructor; // Triângulo (lado, altura)
</script>
Herança de protótipo
HERIDAÇÃO DE PROTOTIPO: No final da cadeia de protótipo, é o objeto de protótipo apontado pelo atributo protótipo do construtor de objeto. Esse objeto de protótipo é o ancestral de todos os objetos, e esse ancestral implementou métodos que todos os objetos como a tostragem deveriam ter de maneira inationária. Outros construtores internos, como função, boolean, string, data e regexp, são herdados desse ancestral, mas cada um define seus próprios atributos e métodos, para que seus descendentes mostrem as características de seus respectivos clãs.
No ECMAScript, o método de implementação de herança é alcançado ao contar com a cadeia de protótipos.
A cópia do código é a seguinte:
<script type = "text/javascript">
Função Box () {// A função herdada é chamada Supertype (classe pai, classe base)
this.name = "jack";
}
Tree de função () {// As funções herdadas são chamadas de subtipos (subclasses, classes derivadas)
this.age = 300;
}
// herdar através da cadeia de protótipo, atribua os atributos do protótipo do subtipo
// new Box () entregará as informações na construção da caixa e as informações no protótipo à árvore
Tree.prototype = new Box (); // Tree herda a caixa e forma uma corrente através do protótipo.
var árvore = nova árvore ();
alerta (árvore.name); // Jack Popt
</script>
Problema com a cadeia de protótipos: embora a cadeia de protótipos seja muito poderosa e possa ser usada para implementar a herança, ela também tem alguns problemas. O problema mais importante vem do protótipo de valor que contém o tipo de referência. Os atributos de protótipo contendo tipos de referência são compartilhados por todas as instâncias; É por isso que os atributos são definidos nos construtores, não em objetos de protótipo. Quando a herança é alcançada através de um protótipo, o protótipo se torna uma instância de outro tipo. Portanto, o atributo de instância original se torna o atributo de protótipo.
Ao criar uma instância de um subtipo, o argumento não pode ser passado para o construtor de supertipo. De fato, deve -se dizer que não há como passar os parâmetros ao construtor de supertipo sem afetar todas as instâncias de objetos. Além do problema que acabamos de discutir devido à inclusão de valores de tipo de referência nos protótipos, é raro usar as cadeias de protótipo somente na prática.
Outra castanha:
A cópia do código é a seguinte:
<script type = "text/javascript">
Pessoa da função (nome)
{
this.name = name; // Definir propriedades do objeto
};
Pessoa.prototype.company = "Microsoft"; // Defina as propriedades do protótipo
Pessoa.prototype.sayhello = function () // Método do protótipo
{
alerta ("Olá, eu sou"+ this.name+ "de"+ this.company);
};
var Billgates = nova pessoa ("Billgates"); // Criar objeto Pessoa
Billgates.sayhello (); // herda o conteúdo do protótipo e saídas "Olá, eu sou Billgates da Microsoft"
var trabalho = nova pessoa ("empregos");
Jobs.company = "Apple"; // Defina seu próprio atributo de empresa para encobrir o atributo da empresa do protótipo
Jobs.Sayhello = function ()
{
alerta ("oi" + this.name + "like" + this.company);
};
Jobs.Sayhello (); // As propriedades e métodos que você se substitui, produz "Oi, empregos como a Apple"
Billgates.sayhello (); // A cobertura de empregos não afeta o protótipo, as billgates ainda são produzidas
</script>
Veja o seguinte exemplo da cadeia de protótipo:
A cópia do código é a seguinte:
<script type = "text/javascript">
função ano () {
this.value = 21;
}
Ano.prototype = {
Método: function () {
}
};
função hi () {
};
// Defina a propriedade Prototype de Hi para o objeto de instância do ano
Oi.prototype = novo ano ();
Oi.prototype.year = 'Hello World';
HI.Prototype.Constructor = HI;
var test = new hi (); // crie uma nova instância de oi
// cadeia de protótipo
Teste [HI Exemplo]
HI.Prototipo [Exemplo do ano]
{Ano: 'Hello World'}
Ano.prototipo
{método:…};
object.prototype
{tostring: ...};
</script>
A partir do exemplo acima, o objeto de teste é herdado de hi.prototype e ano.prototype; Portanto, ele pode acessar o método de protótipo do ano e, ao mesmo tempo, pode acessar o valor da propriedade da instância
__PTOTO__ atributo
O atributo __ptoto__ (não suportado pelo navegador do IE) é um ponteiro para o objeto de protótipo da instância. Sua função é apontar para o construtor de atributos do protótipo do construtor. Através desses dois atributos, você pode acessar as propriedades e métodos no protótipo.
Uma instância de objeto no JavaScript é essencialmente composta por uma série de propriedades. Entre essas propriedades, existe uma propriedade especial internamente invisível - __proto__. O valor dessa propriedade aponta para o protótipo da instância do objeto. Uma instância de objeto possui apenas um protótipo exclusivo.
A cópia do código é a seguinte:
<script type = "text/javascript">
função box () {// uppercase, representando o construtor
Box.prototype.name = "trigkit4"; // atributos de protótipo
Box.prototype.age = "21";
Box.prototype.run = function () // Método do protótipo
{
retornar this.name + this.age + 'estudando';
}
}
var box1 = new Box ();
var box2 = new Box ();
alerta (Box1.Constructor); // Construa o atributo, você pode obter o próprio construtor,
// A função deve ser posicionada pelo ponteiro do protótipo e depois obter o próprio construtor
</script>
A diferença entre o atributo __proto__ e o atributo de protótipo
O protótipo é uma propriedade proprietária no objeto de função.
__proto__ é uma propriedade implícita de um objeto normal. Quando novo, apontará para o objeto apontado pelo protótipo;
__ptoto__ é na verdade um atributo de um determinado objeto de entidade, enquanto o protótipo é um atributo pertencente ao construtor. __ptoto__ só pode ser usado em ambientes de aprendizado ou depuração.
Processo de execução do modo de protótipo
1. Procure os atributos ou métodos na instância do construtor e, se assim for, retorne imediatamente.
2. Se não houver nenhuma instância do construtor, vá para seu objeto de protótipo e retorne imediatamente.
Objeto de protótipo
A cópia do código é a seguinte:
<script type = "text/javascript">
função box () {// uppercase, representando o construtor
Box.prototype.name = "trigkit4"; // atributos de protótipo
Box.prototype.age = "21";
Box.prototype.run = function () // Método do protótipo
{
retornar this.name + this.age + 'estudando';
}
}
var box1 = new Box ();
alert (box1.name); // trigkit4, o valor no protótipo
Box1.name = "Lee";
alerta (box1.name); // lee, vá para o princípio
var box2 = new Box ();
alert (box2.name); // trigkit4, o valor do protótipo, não modificado pela caixa1
</script>
O construtor
A cópia do código é a seguinte:
<script type = "text/javascript">
caixa de função () {
this.name = "Bill";
}
Box.prototype.name = "trigkit4"; // atributos de protótipo
Box.prototype.age = "21";
Box.prototype.run = function () // Método do protótipo
{
retornar this.name + this.age + 'estudando';
}
var box1 = new Box ();
alerta (Box1.name); // Bill, o valor no protótipo
Box1.name = "Lee";
alerta (box1.name); // lee, vá para o princípio
</script>
Para resumir, vamos resolver:
A cópia do código é a seguinte:
<script type = "text/javascript">
function pessoa () {};
Pessoa.prototype.name = "trigkit4";
Person.prototype.say = function () {
alerta ("hi");
}
var p1 = new pessoa (); // protótipo é um protótipo objeto de p1 e p2
var p2 = nova pessoa (); // p2 é um objeto instanciado e há um atributo __proto__ dentro dele, apontando para o protótipo da pessoa
console.log (p1.prototype); // indefinido, esta propriedade é um objeto e não pode ser acessada
console.log (Person.prototype); // Pessoa
console.log (Person.prototype.Constructor); // Há também um ponteiro (propriedade construtora) dentro do protótipo objeto apontando para a função do construtor
console.log (p1 .__ proto __); // Esta propriedade é um ponteiro apontando para o protótipo objeto de protótipo
p1.say (); // instâncias podem acessar propriedades e métodos definidos no objeto de protótipo
</script>
Modelo de fábrica
A cópia do código é a seguinte:
função createObject (nome, idade) {
var obj = new Object ();
obj.name = nome;
obj.age = idade;
retornar obj;
}
O padrão de fábrica resolve o problema da duplicação em larga escala de objetos instantados, mas há outro problema, ou seja, é impossível descobrir qual instância do objeto eles são.
O uso do método do construtor não apenas resolve o problema da instanciação repetida, mas também resolve o problema do reconhecimento de objetos.
A diferença entre usar métodos construtores e padrões de fábrica é que:
1. Crie objeto (novo objeto ()) que não é exibido pelo método do construtor;
2. Atribuir diretamente atributos e métodos a este objeto
3. Sem declaração de retorno
Quando o construtor é usado e o novo construtor () é usado, o novo objeto () é executado em segundo plano;
Isso no corpo da função representa o objeto derivado de novo objeto ()
1. Determine se a propriedade está na instância do construtor ou no protótipo, você pode usar a função `histownsProperty ()`
2. A maneira de criar literais é usada para criar atributos do construtor não apontará para a instância, mas para o objeto, e a maneira de criar construtores é o oposto.
Por que apontar para o objeto? Porque box.prototype = {}; essa maneira de escrever é realmente criar um novo objeto.
Toda vez que uma função é criada, seu protótipo será criado ao mesmo tempo, e esse objeto obterá automaticamente o atributo construtor
3. Se for um método de instância, instanciação diferente, seus endereços de método são diferentes e únicos.
4. Se for um método de protótipo, o endereço deles será compartilhado