Padrão de herança de programação orientada a objetos

O ECMAScript suporta apenas a implementação de herança e, de fato, a herança é alcançada principalmente com base na cadeia de protótipos

Cadeia de protótipo

Como todo objeto e protótipo possui um protótipo, o protótipo do objeto aponta para o objeto do protótipo e o protótipo do pai aponta para o pai do pai.

Ideia básica: use protótipos para permitir que um tipo de referência herde as propriedades e métodos de outro tipo de referência.
A relação entre construtor, protótipo e instância: cada construtor possui um objeto de protótipo, o objeto de protótipo contém um ponteiro para o construtor e a instância contém um ponteiro interno para o objeto de protótipo.

O conceito básico da cadeia de protótipos:
tornar o objeto de protótipo igual a uma instância de outro tipo.O objeto de protótipo no momento conterá um ponteiro para outro protótipo e o outro protótipo também conterá um ponteiro para outro construtor. Supondo que outro protótipo seja outro tipo de instância, o relacionamento acima ainda se mantém, de modo que as camadas de progressividade são suficientes para formar uma cadeia de instâncias e protótipos.
Um modelo básico para implementar uma cadeia de protótipos:

function SuperType(){
	this.property = true;
}
SuperType.prototype.getSuperValue = function(){
	return this.property;
}
fucntion SubType(){
	this.subproperty = fasle;
}
//继承了superType属性和方法
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
	return this.Subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue);//true

O SubType herda o SuperType. A herança é obtida através da criação de uma instância do SuperType e da atribuição a subType.prototype.A
essência da implementação é reescrever o objeto do protótipo e substituí-lo por uma instância de um novo tipo.

O exemplo no exemplo e o relacionamento entre o construtor e o protótipo
Exemplos e construtores e protótipos

① No código acima, não passamos o protótipo padrão SubType, mas substituímos um novo protótipo, que é uma instância do SuperType. O novo protótipo possui apenas todas as propriedades e métodos como uma instância do SuperType, e também existe um ponteiro que aponta para o protótipo do SuperType.
Method O método getSuperValue () ainda está em SuperType.prototype, mas a propriedade está em SubType.prototype, portanto, a propriedade é uma propriedade de instância e getSuperValue () é um método de protótipo. Como SubType.prototype agora é uma instância do SuperType, é claro que a propriedade está nessa instância.
③ No caso de herança através da cadeia de protótipos, o processo de busca é continuar para cima ao longo da cadeia de protótipos.
④ Chamar instance.getSuperValue passará por três etapas de pesquisa: instance Instância de pesquisa ② Search SubType.prototype ③ Search SuperType.prototype

  1. Não se esqueça do protótipo padrão
    . O protótipo padrão de todas as funções é uma instância de Object, portanto, o protótipo padrão conterá um ponteiro interno para Object.prototype. Razão.

  2. Há duas maneiras de determinar o relacionamento entre o protótipo e a instância : ① Use o operador instanceof () para testar a instância e o construtor que apareceu na cadeia do protótipo, e o resultado retornará verdadeiro.
    alert (instance instance of SuperType); // true Object, SuperType, SubType retornam true
    methodUse o método isPrototypeOf (), desde que o protótipo que apareceu no protótipo possa ser considerado o protótipo da instância derivada do
    alerta da cadeia de protótipos (Object .prototype.isPrototypeOf (instance)); // true
  3. Definir métodos cuidadosamente
    Os subtipos às vezes precisam substituir um método em um tipo ou precisam adicionar um método em um supertipo. Mas, em qualquer caso, o código para adicionar métodos ao protótipo deve ser colocado após a instrução de substituição do protótipo
    SubType.prototype = new SuperType ();
    SubType.prototype.getSubValue = function () {// Add method
    return this.Subproperty;
    }
    SubType. prototype.getSuperValue = function () {// Reescreva o método supertype para chamar esse método
    return false;
    }
    Ao herdar através da cadeia de protótipos, você não pode usar a letra do objeto para criar um método de protótipo. Isso reescreverá a cadeia de protótipos
  4. O problema com a cadeia de protótipos O
    principal problema vem do protótipo que contém o valor do tipo de referência
    Ao implementar a herança por meio do protótipo, o protótipo se torna realmente uma instância de outro tipo. Como resultado, os atributos da instância original tornaram-se logicamente os atributos do protótipo atual. (Problema de compartilhamento) O
    segundo problema é: ao criar uma instância de um subtipo, você não pode passar parâmetros para o construtor de supertipos.

Emprestador Construtor

① Resolva o problema causado pelo valor do tipo de referência no protótipo e use a técnica de emprestar o construtor (objeto forjado ou herança clássica).
Idéia: chame o construtor de supertipos dentro do construtor de subtipos.
Function Uma função é apenas um objeto que executa código em um ambiente específico; portanto, os métodos apply () e call () também podem ser usados ​​para executar construtores em (futuros) objetos recém-criados.

function SuperType(){
	this.colors = ["red","green","black"];
}
fucntion SubType(){
	SuperType.call(this);//继承SuperType
}
var instance1 = new SubType();
var instance2 = new SubType();
instance1.colors.push("blue");
alert(instance1.colors);//"red,green,black,blue"
alert(instance2.colors);//"red,green,black"

③ "Secundário" o construtor supertipo. Usando o método call (), na verdade chamamos o construtor SuperType no contexto (por uma questão de) da instância SubType recém-criada. Dessa maneira, todos os códigos de inicialização do objeto definidos na função SuperType () serão executados no novo objeto SubType. Como resultado, cada instância do SubType terá sua própria cópia do atributo colors.

  1. Passando parâmetros
    Você pode passar parâmetros para o construtor de supertipos no construtor de subtipos

     function SuperType(){
       this.name = name;
     }
     fucntion SubType(){
       Super.call(this,"abc");//继承SuperType,同时还传参
       this.age = 29;//实例属性
     }
     var instance = new SubType();
     alert(instance.name);//"abc"
     alert(instance.age);//"29"
    
  2. O problema de pedir emprestado a um construtor
    não pode evitar o problema dos métodos-padrão do construtor; os métodos são definidos no construtor; portanto, é impossível falar sobre a reutilização de funções.

Herança combinada

Também chamada de herança clássica, refere-se a um modelo de herança que combina a cadeia de protótipos e empresta a tecnologia do construtor para dar um toque a ambas.
Idéia: use a cadeia de protótipos para obter a herança das propriedades e métodos do protótipo e peça emprestado o construtor para obter a herança das propriedades da instância. Ele não apenas realiza a reutilização de funções definindo métodos no protótipo, mas também garante que cada instância tenha suas próprias propriedades.

function SuperType(name){//定义两个属性name,colors
	this.name = name;
	this.colors = ["red","green","black"];
}
SuperType.prototype.sayName = function(){//SuperType原型定义一个方法
	return this.name;
}
function SubType(name,age){
	SuperType.call(this,name);//SubType调用SuperType时传入name参数,定义自己的属性age
	this.age = age;
}
SubType.prototype = new SuperType();//SubType的实例赋值给SubType
SubType.prototype。constructor = SubType;
SubType.prototype.satAge = function(){
	alert(this.age);
}
//定义方法这样一来,可以让两个不同的subType实例既分别拥有自己属性包括colors属性也可以使用相同的方法了
var instance1 = new SubType("abc",29);
instance1.colors.push("black");
alert(instance1.colors);//"red,green,blue,black"
instance1.sayName();//"abc"
instance.sayAge();//29
var instance2 = new SubType("Greg",21);
alert(instance1.colors);//"red,green,blue"
instance1.sayName();//"Greg"
instance.sayAge();//21

Herança prototípica

A ideia de Douglas Crockford é que, com a ajuda de protótipos, novos objetos podem ser criados com base em objetos existentes, sem a necessidade de criar tipos personalizados.

function object(o){
	function F(){}
	F.prototype = o;
	return new F();
}
var person = {                     //另一个对象基础是person对象
	name:"A";
	friends:["B","C","D"];
}
var anotherperson = Object(person);
anotherperson.name = "E";
anotherperson.friends.push("F");

var yetAnotherperson = Object(person);
yetAnotherperson.name = "H";
yetAnotherperson.friends.push("I");
alert(person.friends);//"B,C,D,F,I"

Dentro da função object (), um construtor temporário é criado primeiro, depois o objeto passado é usado como o protótipo desse construtor e, finalmente, uma nova instância desse tipo temporário é retornada.
Essencialmente, object () executa uma cópia superficial do objeto passado para ele.
Passe-o para a função object (), que retorna um novo objeto. O novo objeto usa person como um protótipo. Portanto, seu protótipo contém um atributo de valor de tipo básico e um atributo de tipo de referência. person.friends não apenas pertence à pessoa, mas também é compartilhado por outraPerson e ainda outra pessoa. Equivale a criar duas cópias do objeto de pessoa.

A herança prototípica requer que você tenha um objeto que possa ser usado como base para outro objeto. Se houver esse objeto, você pode passá-lo para a função de objeto e modificá-lo de acordo com as necessidades específicas.

O ECMAScript5 padroniza a herança de protótipo adicionando o método Object.create (). Dois parâmetros: um objeto usado como um protótipo para o novo objeto e (opcionalmente) um objeto que define propriedades adicionais para o novo objeto. O mesmo comportamento do método Oject () var anotherperson = Object (person); substitua por var outraperson = Object.create
(person);
var yetAnotherperson = Object (person); substitua por var yetAnotherperson = Object. criar (pessoa);

Herança parasitária

Crie uma função que é usada apenas para encapsular o processo de herança, a função aprimora internamente o objeto de alguma forma e, finalmente, retorna o objeto como se realmente tivesse feito todo o trabalho

function createAnother(original){
	var clone = Object(original);//通过调用函数创建一个新对象
	clone.sayHi = function(){//以某种方式来增强这个对象
		alert("Hi");
	}
	return clone;//返回这个对象
}
var person = {
	name:"A",
	friends:["B","C","D"];
}
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//"Hi"

person retorna um novo objeto-otherPreson.O novo objeto não apenas possui todos os atributos e métodos de person, mas também possui seu próprio método sayHi ().
O uso da herança parasita para adicionar funções aos objetos reduzirá a eficiência devido à incapacidade de reutilizar funções.

Herança combinada parasitária

O maior problema com a herança combinatória é que, independentemente da situação, o construtor de supertipos será chamado duas vezes: uma vez ao criar o protótipo da subclasse e uma vez dentro do construtor da subclasse.
O subtipo eventualmente conterá todos os atributos de instância do objeto supertipo, mas precisamos substituir esses atributos ao chamar o construtor de subtipo,

function SuperType(name){
	this.name = name;
	this.colors = ["red","green","black"];
}
SuperType.prototype.sayName = function(){
	alert(this.name);
}
function SubType(name,age){
	SuperType.call(this,name);//第二次调用superType()在新对象上创建了实例属性name,colors这两个属性就屏蔽了原型中的两个同名属性
	this.age = age;
}
SubType.prototype = new SuperType();//第一次调用superType(),得到两个属性都是superType的实例属性。
SubType.prototype。constructor = SubType;
SubType.prototype.satAge = function(){
	alert(this.age);
}

Escreva dessa maneira, existem dois conjuntos de atributos de nome e cores, um na instância e outro no protótipo subType

Inher Herança de combinação parasitária, isto é, herdar propriedades emprestando construtores e herdar métodos através da forma híbrida de cadeias de protótipos.
Idea Ideia básica: não é necessário chamar o construtor do supertipo para especificar o protótipo do subtipo.Tudo o que precisamos é de uma cópia do protótipo do supertipo.
③ Essência: é para usar a classe de herança parasitária para herdar o protótipo do supertipo e depois atribuir o resultado ao protótipo do subtipo.

function inheritPrototype(subType,superType){
	var prototype = Object(superType.prototype);//创建对象 创建超类型原型的副本
	prototype.construcoter = subType;//增强对象,为创建的副本添加constructor属性
	subType.prototype = prototype;//指定对象,为新创建的对象(副本)赋值给子类型的原型
}

Example O exemplo acima replaced é substituído e passa a herdarProtótipo (SubType, SuperType);
way Dessa forma, a eficiência é aprimorada chamando o construtor SuperType apenas uma vez, evitando assim a criação de propriedades extras desnecessárias no SubType.prototype. Ao mesmo tempo, a cadeia de protótipos pode permanecer inalterada; portanto, instanceof e isPrototypeOf () podem ser usados ​​normalmente.

Publicado 17 artigos originais · elogiado 0 · visitas 761

Acho que você gosta

Origin blog.csdn.net/CandiceYu/article/details/89889081
Recomendado
Clasificación