Protótipo e cadeia de protótipos com profundo conhecimento do JavaScript

Escreva na frente

Protótipos e cadeias de protótipos sempre foram conceitos importantes em JavaScript. Compreendê-los nos ajuda a entender o relacionamento entre tipos de referência predefinidos e o mecanismo de implementação da herança de objetos em JavaScript. A seguir, é apresentado meu entendimento e resumo de protótipos e cadeias de protótipos.

Protótipo

Entendimento de objeto de protótipo

A propriedade prototype do objeto de função

Toda função que criamos possui um atributo prototype, que é um ponteiro para um objeto. O objetivo deste objeto é conter propriedades e métodos que podem ser compartilhados por todas as instâncias de um tipo específico.Em resumo, as propriedades __proto__ de todos os objetos instanciados pela função apontam para esse objeto, que é o protótipo de todos os objetos instanciados da função .

function Person(){
}
// 为原型对象添加方法Person.prototype.sayName = function(){ alert(this.name);}

Vamos olhar para o relacionamento entre eles.

propriedade construtora

Quando a função é criada e a propriedade prototype aponta para um objeto de protótipo, por padrão, o objeto de protótipo receberá uma propriedade de construtor.Esta propriedade é um ponteiro para o objeto de função em que o protótipo está localizado.

Tomando o exemplo anterior, Person.prototype.constructor aponta para o objeto da função Person.

Vamos atualizar o diagrama de relacionamento entre eles.

Atributo __proto__ do objeto

Quando chamamos o construtor para criar uma nova instância, ele conterá um ponteiro dentro da instância que aponta para o objeto protótipo do construtor.Este ponteiro é chamado [[Prototype]] na quinta edição do ECMA-262. Todos os objetos contêm o atributo [[Prototype]], apontando para o objeto prototype, que é um conceito-chave para entender a cadeia de protótipos.

Deve-se observar que não há uma maneira padrão de acessar a propriedade [[Prototype]] no script, mas cada objeto no Firefox, Safari e Chrome suporta uma propriedade __proto__ para acessar. __proto__ para expressar.

De acordo com o construtor Person anterior, criamos uma nova instância

var student = new Person();

console.log(student.__proto__ === Person.prototype); // true

Como podemos ver acima, essa conexão existe entre a instância e o objeto protótipo do construtor, não entre a instância e o construtor.

Vamos dar uma olhada na relação entre esses objetos

isPrototypeOf ()

Embora não tenhamos como acessar a propriedade [[Prototype]] no script, podemos usar o método isPrototypeOf para determinar se esse relacionamento existe entre objetos.

O método isPrototypeOf () é usado para testar se um objeto existe na cadeia de protótipos de outro objeto.

console.log(Person.prototype.isPrototypeOf(student)); // true

Object.getPrototypeOf ()

Um novo método chamado Object.getPrototypeOf () foi adicionado no ECMAScript 5, esse método pode retornar o valor de [[Prototype]] da seguinte maneira

console.log(Object.getPrototypeOf(student) === Person.prototype); // true

Atributo Prototype

Acesso a atributos

Sempre que o código ler um atributo de um objeto, ele primeiro procurará o atributo no próprio objeto e, se o atributo for encontrado, retornará o valor do atributo, se não for encontrado, continuará pesquisando o objeto de protótipo correspondente ao objeto e assim por diante. .

Devido a esse processo de pesquisa, se adicionarmos um atributo à instância, esse atributo protegerá o atributo com o mesmo nome salvo no objeto de protótipo, porque, depois de procurar o atributo na instância, não procuraremos para trás.

Julgamento de atributos

Como um atributo pode ser a própria instância ou seu objeto protótipo, como o julgamos?

No caso em que a propriedade confirma a existência, podemos usar o método hasOwnProperty () para determinar se existe uma propriedade na instância ou no protótipo. Observe que esse método só retorna true se o atributo fornecido existir na instância.

function Person() {};
Person.prototype.name = "laker" ;
var student = new Person();
console.log(student.name); // lakerconsole.log(student.hasOwnProperty("name")); // false

student.name = "xiaoming";console.log(student.name); //xiaoming 屏蔽了原型对象中的 name 属性console.log(student.hasOwnProperty("name")); // true

O exemplo acima é principalmente para o caso em que o atributo é confirmado. Se esse atributo não existir necessariamente, o julgamento não é suficientemente preciso, portanto, primeiro precisamos determinar se o atributo existe e, em seguida, executar a operação de julgamento acima.

Para determinar se um atributo existe, podemos usar o operador in, que retorna true quando o objeto pode acessar um determinado atributo, independentemente de o atributo existir na instância ou no protótipo.

Portanto, podemos encapsular essa função para determinar se existe uma propriedade no protótipo.

function hasPrototypeProperty(object, name){ return !object.hasOwnProperty(name) && (name in object);}

loop for-in

Ao usar um loop for-in, todos os atributos enumeráveis ​​que podem ser acessados ​​por meio do objeto são retornados, incluindo os atributos existentes na instância e os atributos existentes no protótipo.

Uma coisa a observar é que os atributos da instância que mascaram atributos não enumeráveis ​​na instância também serão retornados em um loop for-in.

Obter todos os atributos

Se você deseja obter todas as propriedades de instância enumeráveis ​​em um objeto, pode usar o método Object.keys (). Este método recebe um objeto como parâmetro e retorna uma matriz de string contendo todas as propriedades enumeráveis.

Se você deseja obter todas as propriedades da instância, sejam elas enumeradas ou não, podemos usar o método Object.getOwnPropertyNames ().

Cadeia de protótipo

Entendendo a cadeia de protótipos

O conceito de cadeia de protótipo é descrito no ECMAScript, e a cadeia de protótipo é usada como o principal método para obter herança. A idéia básica é usar um tipo de referência para herdar as propriedades e métodos de outro tipo de referência.

O principal método de implementação da cadeia de protótipos é tornar o objeto protótipo do construtor igual a uma instância de outro tipo.Como o objeto protótipo atualmente é uma instância, ele conterá um ponteiro para outro protótipo e, portanto, outro protótipo também contém um Ponteiro para outro construtor. Se outro protótipo é uma instância de outro tipo, o relacionamento acima ainda é estabelecido, de modo que as camadas de progressividade formam uma cadeia de instâncias e tipos. Este é o conceito básico da cadeia de protótipos.

Vejamos um exemplo.

function Super(){};function Middle(){};function Sub(){};Middle.prototype = new Super();Sub.prototype = new Middle();var suber = new Sub();

Vamos dar uma olhada na relação entre esses objetos

Protótipo padrão

De fato, nossa cadeia de protótipos acima está incompleta.Lembra como dissemos que todos os tipos de referência herdam Object? Essa herança é alcançada através da cadeia de protótipos. Devemos lembrar que 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. Esse é o motivo fundamental pelo qual todos os tipos personalizados herdam os métodos padrão, como toString () e valueOf ().

Então atualizo a cadeia de protótipos acima de nós.

Object.prototype é o fim da cadeia de protótipos, podemos tentar imprimir Object.prototype .__ proto__, descobriremos que ele retornará um objeto vazio nulo, o que significa o fim da cadeia de protótipos.

Funções também são objetos

De fato, a cadeia de protótipos acima ainda está faltando, por quê? Como sabemos que em JavaScript, funções também são objetos, portanto, as funções também devem ter seus objetos protótipos. Vamos entender o relacionamento entre eles através de um exemplo.

Código de exemplo:

function Foo(who) {this.me = who;}
Foo.prototype.identify = function() {return "I am " + this.me;};
function Bar(who) {Foo.call( this, who );}
Bar.prototype = Object.create( Foo.prototype );
Bar.prototype.speak = function() {alert( "Hello, " + this.identify() + "." );};
var b1 = new Bar( "b1" );var b2 = new Bar( "b2" );
b1.speak();b2.speak();

Vamos primeiro examinar o diagrama de relacionamento da cadeia de protótipos incluída no exemplo acima sem o protótipo de função:

A seguir, é apresentado o diagrama de relacionamento da cadeia de protótipos após a adição do protótipo de função.

Escreva no final

Depois de resumir o conhecimento de protótipos e cadeias de protótipos, sinto que o entendimento da linguagem JavaScript é mais profundo e também estabelece as bases para entender a criação e a herança de objetos posteriormente. De fato, para entender a cadeia de protótipos, é fácil entender o comportamento e a implementação de alguns tipos predefinidos em JavaScript.

Publicado 117 artigos originais · 69 elogios · 10.000+ visualizações

Acho que você gosta

Origin blog.csdn.net/zsd0819qwq/article/details/105378892
Recomendado
Clasificación