introduzir
Qualquer programação propõe reutilização de código. Caso contrário, se você precisar escrever um novo programa sempre que desenvolver um novo programa ou escrever uma nova função, será uma parada. No entanto, a reutilização do código também é boa ou ruim. Nos próximos dois artigos, discutiremos a reutilização do código. O primeiro artigo evita o uso desses padrões o máximo possível, porque traz alguns problemas em maior ou menor grau; A segunda linha é a recomendação, que se refere ao padrão recomendado que todos usam, e geralmente não haverá problemas.
Modo 1: modo padrão
Muitas vezes, há um problema com a reutilização do código do modo padrão comumente usado por todos. Este modo usa o construtor Parent () para criar um objeto e atribuir o objeto ao protótipo Child (). Vejamos o código:
A cópia do código é a seguinte:
função herdeira (c, p) {
C.prototype = new p ();
}
// Construtor pai
função pai (nome) {
this.name = nome || 'Adão';
}
// Adicione a função Say Say ao protótipo
Parent.prototype.say = function () {
retornar este.name;
};
// construtor infantil está vazio
função filho (nome) {
}
// Executa a herança
herdar (criança, pai);
Var Kid = New Child ();
console.log (Kid.Say ()); // "Adam"
var Kiddo = New Child ();
Kiddo.name = "Patrick";
console.log (kiddo.say ()); // "Patrick"
// Desvantagens: você não pode passar parâmetros para o construtor infantil
var s = New Child ('Seth');
console.log (s.say ()); // "Adam"
A desvantagem desse modo é que a criança não pode passar os parâmetros, o que é basicamente inútil.
Padrão 2: Construtor de empréstimos
Esse padrão é que a criança empresta o construtor dos pais para aplicar e, em seguida, passa a criança e os parâmetros para o método de aplicação:
A cópia do código é a seguinte:
// Construtor pai
função pai (nome) {
this.name = nome || 'Adão';
}
// Adicione a função Say Say ao protótipo
Parent.prototype.say = function () {
retornar este.name;
};
// Construtor infantil
função filho (nome) {
Parent.Apply (isto, argumentos);
}
Var Kid = New Child ("Patrick");
console.log (Kid.name); // "Patrick"
// Desvantagens: o método Say não é herdado do construtor
console.log (typeof Kid.Say); // "indefinido"
A desvantagem também é óbvia e o método Say não está disponível porque não foi herdado.
Padrão 3: peça emprestado o construtor e defina o protótipo
Os dois modos acima têm suas próprias deficiências, então como remover as deficiências de ambos? Vamos tentar:
A cópia do código é a seguinte:
// Construtor pai
função pai (nome) {
this.name = nome || 'Adão';
}
// Adicione a função Say Say ao protótipo
Parent.prototype.say = function () {
retornar este.name;
};
// Construtor infantil
função filho (nome) {
Parent.Apply (isto, argumentos);
}
Child.prototype = new Parent ();
Var Kid = New Child ("Patrick");
console.log (Kid.name); // "Patrick"
console.log (typeof Kid.Say); // função
console.log (Kid.Say ()); // Patrick
console.dir (garoto);
exclua criança.name;
console.log (Kid.Say ()); // "Adam"
Quando é executado, tudo é normal, mas você notou que o construtor pai foi executado duas vezes; portanto, embora o programa esteja disponível, ele é muito ineficiente.
Modo 4: Protótipo compartilhado
Protótipo compartilhado significa que criança e pai usam o mesmo protótipo, o código é o seguinte:
A cópia do código é a seguinte:
função herdeira (c, p) {
C.Prototype = P.Prototype;
}
// Construtor pai
função pai (nome) {
this.name = nome || 'Adão';
}
// Adicione a função Say Say ao protótipo
Parent.prototype.say = function () {
retornar este.name;
};
// Construtor infantil
função filho (nome) {
}
herdar (criança, pai);
Var Kid = New Child ('Patrick');
console.log (Kid.name); // indefinido
console.log (typeof Kid.Say); // função
Kid.Name = 'Patrick';
console.log (Kid.Say ()); // Patrick
console.dir (garoto);
É certo que o mesmo é verdadeiro, os parâmetros da criança não são recebidos corretamente.
Padrão 5: Construtor temporário
Primeiro, peça emprestado o construtor, depois defina o protótipo filho como uma instância do construtor emprestado e, finalmente, restaure o construtor do protótipo infantil. O código é o seguinte:
A cópia do código é a seguinte:
/* Fechamento*/
var herit = (function () {
var f = function () {
};
Função de retorno (C, P) {
F.Prototype = P.Prototype;
C.prototype = new f ();
C.UBER = P.Prototipo;
C.prototype.Constructor = C;
}
} ());
função pai (nome) {
this.name = nome || 'Adão';
}
// Adicione a função Say Say ao protótipo
Parent.prototype.say = function () {
retornar este.name;
};
// Construtor infantil
função filho (nome) {
}
herdar (criança, pai);
Var Kid = New Child ();
console.log (Kid.name); // indefinido
console.log (typeof Kid.Say); // função
Kid.Name = 'Patrick';
console.log (Kid.Say ()); // Patrick
var kid2 = novo filho ("tom");
console.log (Kid.Say ());
console.log (Kid.Constructor.Name); // Criança
console.log (Kid.Constructor === Parent); // false
O problema ainda é o mesmo, a criança não pode receber parâmetros normalmente.
Modo 6: Klass
Vamos começar com o código para este padrão:
A cópia do código é a seguinte:
var klass = function (pai, adereços) {
var criança, f, i;
// 1.
// novo construtor
Criança = function () {
if (Child.uber && Child.uber.HasownProperty ("__ construto")) {
Criança.UBER .__ construção.Apply (isto, argumentos);
}
if (Child.prototype.HasownProperty ("__ construto")) {
Child.Prototype .__ construto.Apply (isto, argumentos);
}
};
// 2.
// herança
Pai = pai || Objeto;
F = function () {
};
F.Prototype = Parent.prototype;
Child.prototype = new F ();
Child.uber = parent.prototype;
Child.prototype.Constructor = Child;
// 3.
// Adicionar método de implementação
para (i em adereços) {
if (props.HasownProperty (i)) {
Child.Prototype [i] = Props [i];
}
}
// retorna a "classe"
criança de volta;
};
var man = klass (nulo, {
__construct: function (o quê) {
console.log ("construtor do homem");
this.name = o quê;
},
getName: function () {
retornar este.name;
}
});
var primeiro = new Man ('Adam'); // Logs "Construtor do homem"
primeiro.getName (); // "Adam"
Var Superman = Klass (cara, {
__construct: function (o quê) {
console.log ("Construtor do Super -Homem");
},
getName: function () {
var name = superman.uber.getName.call (this);
retornar "eu sou" + nome;
}
});
var Clark = new Superman ('Clark Kent');
Clark.getName (); // "Eu sou Clark Kent"
console.log (Clark Instância de Man); // verdadeiro
console.log (Clark Instância de Superman); // verdadeiro
Que tal? É um pouco tonto de ver? Para ser bom, a gramática e a especificação desse padrão são as mesmas que outros idiomas. Você está disposto a usá -lo? tosse. . .
Resumir
Embora os seis modos acima implementem certas funções em certas circunstâncias especiais, todas elas têm suas próprias deficiências; portanto, em geral, todos devem evitar usá -las.