Se você realmente não consegue entender algum conhecimento naquele momento, pode deixá -lo ir e deixá -lo para o futuro e talvez possa entendê -lo.
Alguns meses atrás, eu estava realizando "JavaScript Advanced Programming (terceira edição)" e, depois de mastigar a criação do objeto, comecei a mastigar a herança. No entanto, depois de mastigar a cadeia de protótipos, eu realmente não aguentava mais, e minha mente se tornou cada vez mais confusa, então joguei de lado e continuei olhando para o último. Agora que usei as férias de verão para entender essa herança, vou resolver minhas anotações.
Encadeamento de protótipo
Vamos ler um artigo primeiro. O autor do artigo é muito bom e está equipado com fotos de alta definição. lol…
Link: [Notas do estudo] Veja a cadeia de protótipos JS de uma pequena perspectiva
Algumas palavras do texto original
Determinar a relação entre protótipo e instância
Existem duas maneiras de detectar o relacionamento entre um protótipo e uma instância:
Instância de: determina se o objeto é uma instância de outro objeto
O mecanismo de computação interno da instância é o seguinte:
functionInstance_of (l, r) {// l representa a expressão esquerda, r representa a expressão direita varo = r.prototype; // pegue o protótipo de exibição de r l = l .__ proto__; // pegue o protótipo implícito de L while (true) {if (l === null) returnfalse; if (o === l) // aqui o ponto: quando o é estritamente igual a l, retorne TruereturnTrue; L = l .__ proto__; }}O código acima é extraído de: análise aprofundada da instância JavaScriptOf
isprototypeof (): testa se existe um objeto na cadeia de protótipos de outro objeto
Consulte as diferenças entre esses dois métodos: JavaScript isPrototypeof vs instância de uso
Use apenas a cadeia de protótipo para obter herança
Desvantagens: 1. Os atributos do protótipo referentes ao valor do tipo serão compartilhados pela instância; 2. Ao criar uma instância de um subtipo, os parâmetros não podem ser passados para o construtor de supertipo.
functionfather () {this.name = "pai"; this.friends = ['aaa', 'bbb'];} functionson () {} son.prototype = newfather (); son.prototype.Constructor = SON; vars1 = Newson (); faterconsole.log (s2.name); // fathers1.name = "filho"; console.log (s1.name); // sonnconsole.log (s2.name); // paterconsole.log (s1.friends); // "aaa", "bbb"] "bbb"] s1.friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] consol.Use apenas construtores para alcançar a herança
Método de implementação: ligue para o construtor de supertipo dentro do construtor de subtipo (usando os métodos Aplicar () e Call ())
Vantagens: resolva o problema de referência de atributos do tipo no protótipo, e as subclasses podem passar parâmetros para superclasses
Desvantagens: as instâncias da subclasse não podem acessar os métodos definidos no protótipo da classe pai (Superclass); portanto, não há como falar sobre a reutilização da função.
functionfather (nome, amigos) {this.name = name; this.friends = Friends;} pad.prototype.getName = function () {returnThis.Name;}; funções (nome) {// NOTA: para garantir que o construtor do pai não substitua as propriedades do filho do construtor, coloque o código que. Padre.call (este, nome, ['aaa', 'bbb']); this.age = 22;} vars1 = newson ('son1'); vars2 = newson ('son2'); console.log (s1.name); // son1console.log (s2.name); SON2S1.friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] console.lort (styts) não pode ser necessário, "aaa", "bbb"]/ sypcl (sypt); // typeError: s1.getName não é uma funções2.getName (); // typeError: s2.getName não é uma funçãoHerança combinada
Método de implementação: use a cadeia do protótipo para implementar a herança de propriedades e métodos do protótipo e use o construtor para implementar a herança das propriedades de instância.
functionfather (nome, amigos) {this.name = nome; this.friends = Friends;} pad.prototype.money = "100k $"; fad.prototype.getName = function () {console.log (this.name); Fad.call (este, nome, ['aaa', 'bbb']); this.age = idade;} // herdar as propriedades e métodos no protótipo da classe pai SON.Prototype = Newfather (); SON.Prototype.Constructor = SON.ProTypeType.GeTage = {) {) {Console.Constructor = SON.On.ProTypeType.GeTage = {) {) {). = Newson ('SON1', 12); s1.friends.push ('ccc'); console.log (s1.friends); // ["aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getName (); // SON1S1.GETAGE (); // 12Vars2 = Newson ('SON2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // SON2S2.getage (); // 24A herança combinada evita o defeito de usar unilateralmente cadeias ou construtores para implementar a herança, combina suas vantagens e se torna o modelo de herança mais comumente usado em JavaScript, mas também é falha, e o defeito da herança combinado será mencionado especificamente mais tarde.
Herança prototípica
Ideia de implementação: use protótipos para criar novos objetos com base em objetos existentes, sem criar tipos personalizados por causa disso.
Para conseguir isso, a seguinte função (OBJ) é introduzida
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} varPerson1 = {name: "Percy", amigos: ['aaa', 'bbb']}; percyconsole.log (Person2.name); // zyjconsole.log (Person1.friends); // ["aaa", "bbb", "ccc"] console.log (PERSON2.Friends); // ["aaa", "bbb", "ccc"] ecmascript 5 normandes); No caso de aprovação em um parâmetro, os métodos object.create () e obj () se comportam o mesmo. VarPerson1 = {Nome: "Percy", Friends: ['aaa', 'BBB']}; varPerson2 = object.Create (Person1); Person2.Name = "Zyj"; Pessoas2.friends.push ('CCC'); Console.Log (Person1.Name); zyjconsole.log (Person1.friends); // ["aaa", "bbb", "ccc"] console.log (Person2.friends); // ["aaa", "bbb", "ccc"]Essa herança pode ser escolhida quando não há necessidade de mobilizar o construtor para criá -la, mas apenas querer que um objeto permaneça semelhante a outro.
Herança parasitária
A herança parasitária é uma idéia intimamente relacionada à herança do protótipo.
Ideia de implementação: Crie uma função usada apenas para encapsular o processo de herança, que aprimora internamente o objeto de alguma forma e finalmente retorna o objeto.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionCreatePerson (original) {// encapsula o processo de herança varclone = obj (original); // crie objeto clone.showsomething = function () {// aprimora console.log ("Hellog"; }; returnclone; // objeto de retorno} VarPerson = {Nome: "Percy"}; VarPerson1 = CreatePerson (Person); Console.log (Person1.name); // Percyperson1.showhething (); // Hello World!Herança de combinação parasita
Vamos falar sobre as deficiências de nossa herança de combinação anterior. O maior problema com a herança combinada é que, independentemente da situação, o construtor da classe pai será chamado duas vezes: um é ao criar o protótipo da subclasse, e o outro é chamado de construtor de subclasse, o construtor da classe pai é chamado dentro do construtor de subclasse.
functionfather (nome, amigos) {this.name = nome; this.friends = Friends;} pad.prototype.money = "100k $"; fad.prototype.getName = function () {console.log (this.name); Padre.call (este, nome, ['aaa', 'bbb']); // A segunda chamada para o pai () é realmente chamada de.age = idade;} // herdar as propriedades e métodos no protótipo da classe pai SON.ProtySTySTYSTRUTRTRUTRO ();A primeira chamada torna o protótipo da subclasse uma instância da classe pai, para que o protótipo da subclasse obtenha o atributo de instância da classe pai; A segunda chamada fará com que o atributo de instância da subclasse também obtenha o atributo de instância da classe pai; e o atributo de instância da subclasse bloqueará os atributos duplicados com o protótipo da subclasse por padrão. Portanto, após essas duas chamadas, os atributos desnecessários aparecem no protótipo da subclasse, introduzindo assim a herança de combinação parasitária para resolver esse problema.
A idéia por trás da herança da combinação parasitária é: não há necessidade de chamar o construtor da classe pai para especificar o protótipo da subclasse. Tudo o que precisamos é de uma cópia do protótipo da classe pai.
Essencialmente, é usar a herança parasitária para herdar o protótipo da classe pai e retornar o resultado ao protótipo da classe infantil.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionIritPrototype (filho, pai) {varprototype = obj (pai.prototype); // crie protótipo de objeto.constructor = filho; // aprimora o objeto SON.Prototype = Prototype; // retorna objeto} functionfather (nome, amigos) {this.name = nome; this.friends = Friends;} pad.prototype.money = "100k $"; pad.prototype.getName = function () {Console.log (this.name);}; o funções (nome, idade) {/ inherit (the de); o the funtionson; Padre.call (este, nome, ['aaa', 'bbb']); this.age = Age;} // herdar as propriedades e métodos no protótipo da classe pai HeritPrototype (filho, pai); filho.prototype.getage = function () {console.log (this.age);}; vars1 = newson ('SON1', 12); s1.fri-ffush ('push); ["aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getName (); // SON1S1.GETAGE (); // 12Vars2 = Newson ('SON2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // SON2S2.getage (); // 24Vantagens: Faça com que os protótipos de subclasse evitem herdar propriedades de instância desnecessárias na classe pai.
Os desenvolvedores geralmente acreditam que a herança combinatória parasitária é o método de herança mais ideal baseado na herança do tipo.
afinal
Finalmente, eu recomendo dois artigos muito difíceis
JavaScript como a herança prototípica realmente funciona
Diagrama de herança clássica de pseudo -de -crimes de JavaScript (precisa atravessar a parede)
Tire uma foto difícil do segundo artigo:
Depois de ler, entendo a cadeia de protótipos em segundos. Há alguma coisa?
O exposto acima é a coleção das informações herdadas por JavaScript. Continuaremos a adicionar informações relevantes no futuro. Obrigado pelo seu apoio a este site!