A explicação da herança de JavaScript foi acordada, mas foi adiada. Sem mais delongas, basta chegar ao ponto.
Como você deseja entender a herança, isso prova que você já tem um certo entendimento do JavaScript, orientado a objetos. Se você não entende nada, pode consultar a explicação básica do JS orientado a objetos, modo de fábrica, modo construtor, modo de protótipo, modo misto, modo de protótipo dinâmico ". Em seguida, vamos falar sobre a herança do JavaScript geralmente através desses métodos.
Cadeia de protótipo
A maneira mais fácil de implementar a herança no JavaScript é usar uma cadeia de protótipo e apontar o protótipo do tipo de criança para uma instância do tipo pai, ou seja, "subtype.prototype = novo tipo pai ()". O método de implementação é o seguinte:
// Crie uma função construtora supertype () {this.name = ['wuyuchang', 'jack', 'tim']; this.Property = true;} // Adicione método supertype.prototype.getSuerPerValue = function () {return this.Property;} // crie uma função de construtor subtype () {this.test = ['h1', 'h2', 'h3', 'h4']; this.subProperty = false;} // Etapas -chave para implementar a herança, o protótipo do subtipo aponta para uma instância do tipo pai subtype.prototype = new Supertype (); // Adicione um método ao tipo de criança aqui. Deve ser que a herança seja implementada, caso contrário, o ponteiro será apontado para uma instância do tipo pai e o método está vazio. Subtype.prototype.getsubValue = function () {return this.subProperty;}/* A seguir, é apresentado um exemplo de código de teste*/var instance1 = new Subtype (); instance1.name.push ('wyc'); instance1.test.push ('h5'); alert (alert (°1.getPer); // Truealert (instance1.getSubValue ()); // FalsEalert (instance1.name); // Wuyuchang, Jack, Tim, Wycalert (Instance1.test); // H1, H2, H3, H4, H5VAR Instância2 = new Subtype (); Alert (Instance2.Name); // Wuyuchang, Jack, Tim, Wycalert (instance2.test); // H1, H2, H3, H4Você pode ver que o código acima é uma herança simples implementada através da cadeia de protótipo, mas ainda existem alguns problemas no exemplo do código de teste. I believe that after reading my blog post "Basic Explanation of Object-Oriented JS, Factory Mode, Constructor Mode, Prototype Mode, Mixed Mode, Dynamic Prototype Mode", I must know that the first problem with the prototype chain code is that the prototype of the subtype is an instance of the parent type, that is, the attributes of the parent type contained in the prototype of the subtype, which causes the prototype attributes that Referência O valor do tipo será compartilhado por todas as instâncias . A instância1.name.push ('wyc'); do código acima pode provar a existência desse problema. O segundo problema com a cadeia de protótipo é que, ao criar uma instância de um subtipo, os parâmetros não podem ser transmitidos para o construtor de supertipo . Portanto, no desenvolvimento real, raramente usamos as cadeias de protótipos sozinhas.
Construtor emprestado
Para resolver dois problemas na cadeia de protótipos, os desenvolvedores começaram a usar uma técnica chamada construtores de empréstimos para resolver problemas na cadeia de protótipo. A idéia de implementação dessa tecnologia também é bastante simples. Você só precisa chamar o construtor do tipo pai no construtor do subtipo. Não se esqueça de que as funções são apenas objetos que executam o código em um ambiente específico, para que os construtores possam ser executados através do método Apply () ou Call () . O código é o seguinte:
// Crie uma função construtora supertype (nome) {this.name = name; this.color = ['rosa', 'amarelo']; this.property = true; this.testfun = function () {alert ('http://tools.vevb.com/'); }} // Adicionar método superetype.prototype.getSuerPerValue = function () {return this.Property;} // Crie uma função de construtor subtype (name) {supertype.call (this, nome); this.test = ['h1', 'h2', 'h3', 'h4']; this.subProperty = false;} // Adicione um método ao subtipo aqui. Be sure to implement inheritance, otherwise the pointer will be pointed to an instance of the parent type, and the method is empty SubType.prototype.getSubValue = function() { return this.subproperty;}/* The following is a test code example*/var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']); instance1.name.push ('hello'); instance1.test.push ('h5'); instance1.color.push ('azul'); instance1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, Hello // alert (Instance1.getSuerPerValue ()); // alerta de erro (instance1.test); // H1, H2, H3, H4, H5 Alert (Instance1.getSubValue ()); // false alert (instance1.color); // rosa, amarelo, Bluevar Instância2 = novo subtipo ('wyc'); instance2.testfun (); // http://tools.vevb.com/alert(instance2.name); // wyc // alert (instance2.getSuerPerValue ()); // alerta de erro (instance2.test); // h1, h2, h3, h4Alert (instance2.getSubValue ()); // FalsEalert (instance2.color); // rosa, amareloVocê pode ver que, no código acima, o construtor do subtipo de subtipo no código acima, a herança do atributo é realizada chamando o tipo pai de "supertype.call (this, nome);". Você também pode passar parâmetros para o tipo pai quando o subtipo é criado, mas um novo problema está chegando. Você pode ver que eu defini um método no construtor do tipo pai: testfun e um método no protótipo do tipo pai: getSuperValue. No entanto, após instanciar o subtipo, ainda é impossível chamar o método getSuperValue definido no protótipo do tipo pai e só pode chamar o método do construtor no tipo pai: testfun. É o mesmo que usar apenas o modo construtor na criação de objetos, para que a função não tenha reutilização. Levando esses problemas em consideração, as técnicas de construtores de empréstimos raramente são usadas sozinhas.
Herança combinada (cadeia de protótipo + construtor de empréstimo)
Como o nome sugere, a herança combinada é um padrão composto pelas vantagens de combinar o uso de cadeias de protótipo e construtores de empréstimos. A implementação também é muito simples. Como é uma combinação, é claro que combina as vantagens de ambas as partes, a saber , o método de herança da cadeia do protótipo e os atributos do construtor herda . O código específico é implementado da seguinte maneira:
// Crie uma função construtora supertype (nome) {this.name = name; this.color = ['rosa', 'amarelo']; this.property = true; this.testfun = function () {alert ('http://tools.vevb.com/'); }} // Adicionar método superetype.prototype.getSuerPerValue = function () {return this.Property;} // Crie uma função de construtor subtype (name) {supertype.call (this, nome); this.test = ['h1', 'h2', 'h3', 'h4']; this.subProperty = false;} subtype.prototype = new supertype (); // Adicione um método ao subtipo aqui. It must be after inheritance is implemented, otherwise the pointer will be pointed to an instance of the parent type, and the method is empty SubType.prototype.getSubValue = function() { return this.subproperty;}/* The following is a test code example*/var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']); instance1.name.push ('hello'); instance1.test.push ('h5'); instance1.color.push ('azul'); instance1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, HelloAlert (Instance1.getSuerPerValue ()); // Truealert (Instance1.test); // H1, H2, H3, H4, H5 Alert (Instance1.getSubValue ()); // false alert (instance1.color); // rosa, amarelo, Bluevar Instância2 = novo subtipo ('wyc'); instance2.testfun (); // http://tools.vevb.com/alert(instance2.name); // wyc alert (instance2.getSuerPerValue ()); // Truealert (instance2.test); // h1, h2, h3, h4Alert (instance2.getSubValue ()); // FalsEalert (instance2.color); // rosa, amareloO código acima herda as propriedades do tipo pai através do supertype.call (este, nome); e herda os métodos do tipo pai através de subtipo.prototype = new Supertype ();. O código acima resolve convenientemente os problemas encontrados por cadeias de protótipo e construtores de empréstimos e se tornou o método de herança de instância mais comumente usado no JavaScript. No entanto, o modo misto não deixa de ter suas deficiências. Pode -se observar que, no código acima, os atributos do tipo pai foram realmente herdados ao herdar o método. No entanto, o tipo de referência é compartilhado neste momento. Portanto, o construtor do tipo pai é chamado no construtor do tipo de criança após o subtipo, herdando assim os atributos do tipo pai para substituir os atributos herdados no protótipo. Obviamente, não é necessário chamar o construtor duas vezes, mas existe alguma maneira de resolvê -lo? Ao resolver esse problema, primeiro veja os dois modos a seguir.
Herança de protótipo
O método de implementação de herança do protótipo é diferente da da herança comum. A herança do protótipo não usa um construtor no sentido estrito, mas, em vez disso, usa o protótipo para criar novos objetos com base em objetos existentes, e não há necessidade de criar tipos personalizados como resultado. O código específico é o seguinte:
função objeto (o) {função f () {} f.prototype = o; devolver novo f ();}Exemplo de código:
/* Herança protótipo*/objeto função (o) {função f () {} f.prototype = o; retornar novo f ();} var pessoa = {nome: 'wuyuchang', amigos: ['wyc', 'nicholas', 'tim']} var o outro outroperseson.name = 'Greg'; outroperseson.friends.push ('bob'); var de outro lugar2 = objeto (pessoa); outroperseson2.name = 'Jack'; outroPerson2.friends.push ('rose'); alerta (pessoa.friends); // WYC, Nicholas, Tim, Bob, RoseHerança parasitária
/* Herança parasitária*/função criativa (original) {var clone = objeto (original); clone.sayhi = function () {alert ('hi'); } retornar clone;}Exemplo de uso:
/* Herança protótipo*/objeto função (o) {função f () {} f.prototype = o; Retornar novo f ();} /* herança parasitária* /função criativa (original) {var clone = objeto (original); clone.sayhi = function () {alert ('hi'); } retornar clone;} var pessoa = {name: 'wuyuchang', amigos: ['wyc', 'nicholas', 'rose']} var outropeson = createanOther (pessoa); outroperseson.sayhi ();Herança de combinação parasita
Mencionei anteriormente as desvantagens da implementação do padrão de combinação da herança em JavaScript. Agora vamos resolver suas deficiências. A idéia de implementação é herdar atributos para os construtores, e o método de herança da forma mista da cadeia do protótipo não precisa instanciar o construtor do tipo pai ao herdar o método. O código é o seguinte:
função objeto (o) {função f () {} f.prototype = o; retornar nova herança f ();}/* herança de combinação parasitária*/função heritprototype (subtipo, supertype) {var prototype = object (supertype.prototype); prototype.constructor = subtipo; subtype.prototype = prototype;}Ao usá -lo, você só precisa substituir a linha de código "subtype.prototype = new supertype ();" No modo de combinação com herdprototipo (subtipo, supertipo);. A eficiência da herança combinatória parasitária se reflete, pois chama o construtor do tipo pai apenas uma vez, evitando a criação de propriedades desnecessárias ou redundantes. Ao mesmo tempo, a cadeia de protótipo pode permanecer inalterada; portanto, a instância e o isPrototypeOf () também pode ser usada normalmente. No momento, esse também é o método de herança mais ideal e atualmente está se transformando nesse modelo. (Yui também usa esse modo.)
Esta postagem do blog refere -se a "JavaScript Advanced Programming 3rd Edition". O código é reescrito e mais específico e comentado para facilitar a compreensão de todos. Se você tiver informações únicas sobre a herança do JS, não seja mesquinho. Responda às suas opiniões para sua referência!