Prefácio
Eu vi uma pergunta como esta no segmentfault:
var f = function () {}; object.prototype.a = function () {}; Function.prototype.b = function () {}; var f = new f ();P: F pode obter A e B? Qual é o princípio?
À primeira vista, fiquei realmente confuso. Depois de um estudo cuidadoso, descobri que ainda não entendi completamente o protótipo, então resumi e preenchi um buraco ~
Função e objeto
Antes de resolver o problema, vamos falar sobre o protótipo, a cadeia de protótipos e a relação entre função e objeto, que também é o foco deste artigo.
protótipo
Ao criar uma função, um objeto de protótipo será criado automaticamente para ele, que pode ser acessado através da propriedade Prototype da função.
Crie um objeto de instância do construtor, que conterá um ponteiro (propriedade interna) dentro dele, apontando para o protótipo objeto do construtor. ECMA-262 A 5ª edição deste ponteiro é chamada [[protótipo]]. Embora não exista uma maneira padrão de acessar [[protótipo]] nos scripts, Firefox, Safari e Chrome, suportam uma propriedade __proto__ em cada objeto para acessar o objeto protótipo de seu construtor.
Deixe -me dizer algo importante novamente:
O construtor acessa o objeto de protótipo através da propriedade Prototype.
O objeto de instância acessa o objeto protótipo através do atributo interno [[protótipo]], e o navegador implementa o atributo _proto_ para o objeto de instância para acessar o objeto Prototype.
var f = function () {}; var f = new f (); // assumindo que o protótipo objeto de f é p, então // f.prototype === p; // f .__ proto__ === p;Repita novamente. . O protótipo refere -se à relação entre o construtor e o objeto de protótipo, e __proto__ refere -se à relação entre o objeto de instância e o objeto de protótipo.
Cadeia de protótipo
A classe A herda B, B herda C ... Na verdade, existe um protótipo objeto com um ponteiro apontando para B no objeto protótipo de A e um objeto de protótipo com um ponteiro apontando para C no objeto de protótipo ... Observe que é a conexão entre os objetos do protótipo. Não há relação entre os três construtores do ABC, por isso é chamado de "cadeia de protótipo" ~
Supondo que A seja um objeto de instância de A, a cadeia de protótipo de A é mostrada na linha roxa na figura abaixo, e a linha laranja conecta o construtor e seu objeto de protótipo.
Como pode ser visto na figura, o final da cadeia do protótipo é objeto.Prototype .__ Proto__ isto é, nulo. Ao procurar uma propriedade ou método de A, primeiro procure se um próprio tem ou não. Caso contrário, pesquise ao longo da cadeia de protótipo até que seja encontrado ou finalmente retornado a indefinido após o NULL.
Função e objeto
A relação entre função e objeto está um pouco emaranhada:
Objeto é um construtor. Como é uma função, é o objeto de instância da função; A função é um construtor, mas function.prototype é um objeto. Como é um objeto, é o objeto de instância do objeto.
Todos os objetos são instâncias de objeto e todas as funções são instâncias de função.
O objeto é uma instância da função e função.Prototype é uma instância do objeto.
A relação entre os dois é mostrada na figura abaixo.
Como pode ser visto, objeto como construtor, ele possui o atributo protótipo apontando para objeto.prototipo e, como um objeto de instância, ele tem o objeto .__ Proto__ apontando para funcionar.Prototype. A função é um construtor, possui um atributo de protótipo apontando para a função.prototipo, e a função é uma função, e também é uma instância de função, por isso tem função .__ Proto__ apontando para a função.Protótipo, então function .__ proto__ === Função.Protótipo é verdadeiro.
Pode ser verificado no console do Chrome, como mostrado na figura.
Análise da pergunta original
A melhor maneira de resolver o problema da cadeia de protótipos é desenhar um quadro. Após a análise anterior, essa imagem não deve ser um problema, como segue ~
A cadeia de protótipos de F é desenhada por uma linha azul, para que F possa acessar A, mas B não pode acessar.
Se você não desenhar uma imagem, à primeira vista, pode pensar que F pode acessar b. Pode ser como eu que o f.prototipo aponte para function.prototype, mas, de fato, o f.prototipo é um objeto e não uma função; portanto, seu objeto de protótipo não será função.Prototype.
Portanto, você deve desenhar uma imagem sempre que o problema da cadeia de protótipos é ~
Tópico estendido
Na pergunta acima, F pode acessar apenas A, mas não b. Mas F pode acessar A e B. Se você modificar a pergunta para o seguinte, qual é o resultado do FB ()? Por que? Você pode pensar sobre isso ~
var f = function () {}; object.prototype.a = function () {}; Function.prototype.b = function () {console.log ('f .__ proto__')}; F.prototype.b = function () {console.log ('f.prototype');};Resumir
Depois de ler isso, você encontrou um recurso especial da função?
Para um objeto geral, existe apenas um atributo __proto__ usado para acessar o protótipo objeto de seu construtor e, para uma função, é uma função e um objeto.
Como função, ele nasce com um atributo de protótipo apontando para o nome do protótipo de função do objeto.Prototype.
Como objeto de instância da função, ele tem o atributo __proto__ apontando para a função.prototype
Geralmente, essas duas propriedades apontam para dois objetos, mas ambas as propriedades da função apontam para o mesmo, ambos apontam para funcionar.prototipo.
Para a função A (), os métodos no A.Prototype são para chamada para seu objeto de instância e não serão usados por si só; Quando A é executado como uma instância, os métodos em um proto__ são chamados. Em outras palavras, quando usado como construtor, a cadeia A.Prototype é tomada, e os métodos e atributos são atribuídos aos seus exemplos; Quando usado como objeto, a cadeia A .__ Proto__ é tomada. Em diferentes cenários, não é errado distinguir sua identidade.
Após todo o artigo, sinto que o que eu disse está bastante irritado ... por favor, corrija -me se houver alguma falha ~ Quanto à pergunta, eu realmente não sei como chamá -lo. .
Que este artigo traga alguns ganhos depois de lê -lo ~ ^_ ^
Obrigado pelo seu apoio a este site. Continuaremos a atualizar informações relevantes no futuro para ajudá -lo a aprender e entender essa parte do conhecimento!