Protótipo JavaScript e cadeia de protótipos (ênfase)

Protótipo de objeto protótipo

  • Todo objeto de função tem uma propriedade de protótipo, mas os objetos comuns não.
  • Objetos comuns são criados por meio de funções

De todas as propriedades definidas pelo núcleo ECMAScript, a mais intrigante é a propriedade protótipo. Para tipos de referência em ECMAScript, o protótipo é o local real onde todos os seus métodos de instância são armazenados. Em outras palavras, métodos como toString() e valueOf() são realmente armazenados sob o nome do protótipo, mas são acessados ​​por meio da instância do respectivo objeto. ---- "Programação avançada de JavaScript"

Todos os objetos JS são divididos em objetos de função e objetos comuns. Todos os objetos criados por new Function() são objetos de função. Os objetos de função têm uma propriedade protótipo e uma propriedade proto.

protótipo

Para alcançar uma herança simples no início do projeto JS, foi introduzido o atributo protótipo, também chamado de objeto protótipo (protótipo explícito).

//原型对象
function Animal(){
    
    };  

console.log(typeof Animal.prototype) //Object  
console.log(typeof Object.prototype) // Object  

Pode-se ver que, em essência, o protótipo é um objeto comum, que é uma instância criada pelo construtor do objeto função. Equivale a criar automaticamente uma instância de Animal quando ele é criado e atribuir essa instância ao protótipo.

Mas há um caso especial de Function, Function.prototype é um objeto protótipo, mas sua essência é um objeto function. Como um objeto de função, não há propriedade de protótipo

console.log(typeof Function.prototype) // 特殊 Function  
console.log(typeof Function.prototype.prototype) //undefined 函数对象却没有prototype属性

atributo proto
Todos os objetos obj (exceto nulo e indefinido) têm um atributo proto (protótipo implícito), o atributo proto é essencialmente um ponteiro para o atributo protótipo do objeto de função que cria o objeto obj.

//创建构造函数
        function Animal(name,age){
    
    
            this.name = name;
            this.age= age;
        }
        Animal.prototype = {
    
    
            alertName(){
    
    
                alert(this.name);
            }
        }
        //创建实例
        var dog = new Animal("大黄");
        dog .print = function(){
    
    
             alert(this.name);
        }
        dog.print();  //大黄
        dog.alertName();  //大黄

O método print() é um método da própria instância dog, então dog.print() gera "rhubarb"; alertName() não é um método da instância dog, mas um método do construtor, e dog.alertName() também produzirá "rhubarb" , porque a instância do cão herda o método do construtor.

O protótipo implícito da instância dog aponta para o protótipo explícito de seu construtor, que significa igual a, ou seja

dog.__proto__ === Animal.prototype// true

construtor construtor

O construtor constructor é usado para construir o objeto de função e o atributo constructor retorna uma referência ao objeto de função que criou esse objeto. Em termos leigos, refere-se ao pai do objeto atual

function Dog(){
    
    };
console.log(a.constructor===Function); //true
console.log(a.prototype.constructor===a); //true

A função a é criada por Function, então seu construtor aponta para Function, a.prototype é criado por new a(), então a.prototype.constructor deve apontar para a.

cadeia de protótipo

A cadeia de protótipos é a principal forma de implementar a herança em JS. A ideia básica é permitir que um tipo de referência herde as propriedades e métodos de outro tipo de referência.

function Animal(){
    
      
    this.animalType = "animal";  
}  
Animal.prototype.getAnimalType = function(){
    
      
    return this.animalType ;  
}  

function Dog(){
    
      
    this.Dogtype = "dog";  
}  
Dog.prototype = new Animal();  

Dog.prototype.getDogType = function(){
    
      
    return this.Dogtype ;  
}  

var dahuang = new Dog();

alert(dahuang.getAnimalType ());// animal

O resultado da impressão de dahuang.getAnimalType() é animal. Dahuang em si não possui um método getAnimalType(), então ele vai procurar em seu proto (ou seja, o protótipo de seu construtor), e descobrir que não existe tal coisa em Cachorro, então siga o proto e vá até Find, Animal.prototype.getAnimalTypefind e retorne o resultado.

如果Animal中还是没有,就接着往上找,一直到Object.prototype原型对象终止

  • Resumindo, a cadeia de protótipos é:
    se a propriedade necessária ou referência de método não for encontrada no objeto, o mecanismo pesquisará no objeto associado a [[protótipo]]. Da mesma forma, se a referência solicitada não for encontrada neste último, continuará a procurá-la [[protótipo], e assim sucessivamente. Até que Object.prototypeo objeto protótipo seja encerrado, esta é a cadeia de protótipos. Object.prototypeé o topo da cadeia de protótipos.

如果找到Object.prototype上还找不到,原路返回,告诉实例此方法或属性没有找到或者没有定义。如果说在中间的任意一个环节找到了,就停止向上查找直接返回结果

O papel dos objetos protótipos e das cadeias protótipos

Se houver muitas propriedades e métodos no construtor, todos os objetos instanciados do construtor compartilham essas propriedades e métodos. Quando várias instâncias desejam compartilhar essas coisas, cada instância copia uma cópia, resultando em É um grande desperdício de recursos, é possível considerar armazenar essas propriedades e métodos que precisam ser compartilhados em uma coisa comum. Essa coisa comum é o objeto protótipo (protótipo).

当然原型链实现继承也会存在一些问题,最主要的问题来自包含引用类型的原型。其次就是在创建子类型的实例时,不能向超类型的构造函数中传递参数。

O relacionamento entre construtores, objetos de instância e objetos de protótipo

insira a descrição da imagem aqui

Qualquer função tem uma propriedade de protótipo, que é um objeto.

function F () {}
console.log(F.prototype) // => object

F.prototype.sayHi = function () {
  console.log('hi!')
}

O objeto do construtor prototypepossui uma constructorpropriedade por padrão, que aponta para prototypea função do objeto.

console.log(F.constructor === F) // => true

O objeto de instância obtido por meio do construtor conterá um prototypeponteiro para o objeto do construtor__proto__

var instance = new F()
console.log(instance.__proto__ === F.prototype) // => true

__proto__é uma propriedade não padrão.

Os objetos de instância podem acessar diretamente os membros do objeto de protótipo.

instance.sayHi() // => hi!

Resumir:

  • Qualquer função tem uma prototypepropriedade que é um objeto
  • O objeto do construtor prototypepossui uma constructorpropriedade por padrão, apontando para prototypea função onde o objeto está localizado
  • O objeto de instância obtido por meio do construtor conterá um prototypeponteiro para o objeto do construtor__proto__
  • Todas as instâncias herdam direta ou indiretamente membros do objeto protótipo

Acho que você gosta

Origin blog.csdn.net/weixin_45576567/article/details/102788716
Recomendado
Clasificación