function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
Ele sempre retorna o objeto com classificação = 3.
Mas se eu fizer o seguinte:
newtoy.__proto__.__proto__.__proto__
A corrente acaba retornando null
.
Também no Internet Explorer, como verificaria o nulo se não houver uma __proto__
propriedade?
javascript
inheritance
prototype-programming
xdevel2000
fonte
fonte
newtoy.prototype
não é igualnewtoy.constructor.prototype
e, portantonewtoy.constructor.prototype
, não terá propriedade chamadarating
. Da mesma formanewtoy.constructor.prototype.constructor.property
também não terá propriedade chamadarating
.newtoy.constructor.prototype
haverá propriedade chamada classificação. Da mesma formanewtoy.constructor.prototype.constructor.property
também terá propriedade chamada classificação.__proto__
vs.prototype
em JavaScript e como o JavaScript.prototype
funciona?Respostas:
Eu estive tentando entender isso recentemente e finalmente criei esse "mapa" que acho que lança luz sobre o assunto
http://i.stack.imgur.com/KFzI3.png
Eu sei que não sou o primeiro a inventar isso, mas foi mais interessante descobrir do que encontrar :-). Enfim, depois disso eu encontrei, por exemplo, outro diagrama que acho que diz basicamente o mesmo:
Layout de objeto Javascript
A coisa mais surpreendente para mim foi descobrir que
Object.__proto__
aponta paraFunction.prototype
, em vez deObject.prototype
, mas tenho certeza de que há uma boa razão para isso :-)Eu colo o código mencionado na imagem aqui também para se alguém quiser testá-lo. Observe que algumas propriedades são adicionadas aos objetos para facilitar saber onde estamos depois de alguns saltos:
fonte
Object.__proto__
aponta paraFunction.prototype
é porque,Object()
por si só, é uma função nativa que instancia um objeto vazio. Portanto,Object()
é uma função. Você verá que todas as outras__proto__
propriedades dos principais tipos nativos apontam paraFunction.prototype
.Object
,Function
,String
,Number
, EArray
todos herdar o protótipo da função.Object
em si é uma função; o resultado da execução de chamadaObject
(ou seja, valor de retorno da execuçãoObject()
) não é uma função.constructor
é uma propriedade [[DontEnum]] predefinida do objeto apontado pelaprototype
propriedade de um objeto de função e inicialmente apontará para o próprio objeto de função.__proto__
é equivalente à propriedade interna [[Prototype]] de um objeto, ou seja, seu protótipo real.Quando você cria um objeto com o
new
operador, sua propriedade [[Prototype]] interna será definida como o objeto apontado pelaprototype
propriedade da função do construtor .Isso significa que
.constructor
avaliaremos a.__proto__.constructor
função construtora usada para criar o objeto e, como aprendemos, aprotoype
propriedade dessa função foi usada para definir o [[Protótipo]] do objeto.Daqui resulta que
.constructor.prototype.constructor
é idêntico a.constructor
(desde que essas propriedades não tenham sido substituídas); veja aqui para uma explicação mais detalhada.Se
__proto__
estiver disponível, você pode percorrer a cadeia de protótipos real do objeto. Não há como fazer isso no ECMAScript3 simples, porque o JavaScript não foi projetado para hierarquias profundas de herança.fonte
.constructor.prototype
encadeamento. Eu também não estava claro para mim, enquanto não via que isso.constructor
é igual.__proto__.constructor
. O que significa simplesmente alternar entre a função do construtor e seu protótipo.A herança prototípica no JavaScript é baseada na
__proto__
propriedade, no sentido de que cada objeto está herdando o conteúdo do objeto referenciado por sua__proto__
propriedade.A
prototype
propriedade é especial apenas paraFunction
objetos e somente ao usar onew
operador para chamar umFunction
como construtor. Nesse caso, os objetos criados__proto__
serão configurados como construtoresFunction.prototype
.Isso significa que adicionar a
Function.prototype
refletirá automaticamente sobre todos os objetos aos quais__proto__
está fazendo referênciaFunction.prototype
.Substituir construtores
Function.prototype
por outro objeto não atualizará a__proto__
propriedade de nenhum dos objetos já existentes.Observe que a
__proto__
propriedade não deve ser acessada diretamente, Object.getPrototypeOf (object) deve ser usado.Para responder à primeira pergunta, criei um diagrama
__proto__
eprototype
referências sob medida , infelizmente o stackoverflow não me permite adicionar a imagem com "menos de 10 reputação". Talvez outra hora.[Editar] A figura usa em
[[Prototype]]
vez de__proto__
porque é assim que a especificação ECMAScript se refere a objetos internos. Espero que você possa descobrir tudo.Aqui estão algumas dicas para ajudar você a entender a figura:
Observe que a
constructor
propriedade não existe nos objetos criados, mas é herdada do protótipo.fonte
new MyFunction()
cria uma instância de objeto à qual__proto__
deve se referir ao seu protótipo de ctor, que éMyFunction.prototype.
Então, por que seMyFunction.prototype.__proto__
refereObject.prototype
? deve referene (como minha primeira amostra) para o protótipo da sua ctor que éMyFunction.prototype
(note queMyFunction.prototype
é um instnace deMyfunction
)Object
é Eva, eFunction
é Adão, Adão (Function
) usa seu osso (Function.prototype
) para criar Eva (Object
). Então quem criou Adam (Function
)? - O inventor da linguagem JavaScript :-).De acordo com a resposta da utsaina, quero adicionar mais informações úteis.
Não deveria ser.
Object.__proto__
NÃO deve apontar paraObject.prototype
. Em vez disso, a instância deObject
o
,o.__proto__
deve apontar paraObject.prototype
.(Perdoe-me por usar os termos
class
einstance
em JavaScript, mas você sabe disso :-)Eu acho que a classe em
Object
si é uma instânciaFunction
, é por issoObject.__proto__ === Function.prototype
. Portanto:Object
é Eva, eFunction
é Adão, Adão (Function
) usa seu osso (Function.prototype
) para criar Eva (Object
).Além disso, até a
Function
própria classe é uma instância deFunction
si mesma, ou seja,Function.__proto__ === Function.prototype
, é também por isso queFunction === Function.constructor
Além disso, a classe regular
Cat
é uma instância deFunction
, isto éCat.__proto__ === Function.prototype
.A razão para o exposto acima é que, quando criamos uma classe em JavaScript, na verdade, estamos apenas criando uma função, que deve ser uma instância de
Function
.Object
eFunction
são apenas especiais, mas ainda são aulas, enquantoCat
é uma aula regular.Por uma questão de fator, no mecanismo JavaScript do Google Chrome, os seguintes 4:
Function.prototype
Function.__proto__
Object.__proto__
Cat.__proto__
Eles são todos
===
(absolutamente iguais) aos outros 3, e seu valor éfunction Empty() {}
ESTÁ BEM. Então quem cria o special
function Empty() {}
(Function.prototype
)? Pense nisso :-)fonte
function Empty() {}
você se refere como sendo igual a Function.prototype, etc ?, qual é o código que você usou no console do Chrome?function Empty() {}
no Google Chrome. Eu também adicionei a saída do console._ _proto_ _
) do Function.prototype. É tão simples como isso :)Realmente não sei por que as pessoas não o corrigiram sobre o problema real de sua compreensão.
Isso facilitaria muito a localização do problema
Então, vamos ver o que está acontecendo:
Ótimo, agora vamos ver isso
__proto__
Antes disso, lembre-se de duas coisas sobre
__proto__
:Quando você cria um objeto com o
new
operador, seu interno[[Prototype]]
/proto__
propriedade será definido como aprototype
propriedade (1) do seuconstructor function
ou "criador", se desejar.Codificado no JS -:
Object.prototype.__proto__
isnull
.Vamos nos referir a esses 2 pontos como "
bill
"Melhor?
fonte
Todas as funções criam seu protótipo. E quando criamos um objeto usando esse construtor de funções, a propriedade __proto__ do meu objeto começa a apontar para o protótipo dessa função.
fonte
__proto__
propriedade.Se todos esses números forem impressionantes, vamos dar uma olhada no significado das propriedades.
STH.prototype
Ao criar uma nova função, há um objeto vazio sendo criado em paralelo e vinculado à função com
[[Prototype]]
cadeia. Para acessar esse objeto, usamos aprototype
propriedade da funçãoTer em mente que
prototype
propriedade está disponível apenas para funções.STH.constructor
O objeto de protótipo mencionado acima não possui propriedades, exceto uma -
constructor
. Esta propriedade representa uma função que criou o objeto protótipo.Ao criar a
Gadget
função, também criamos um objeto{constructor: Gadget}
- que não é nada parecidoGadget.prototype
. Comoconstructor
se refere a uma função que criou um protótipo de objeto,toy.constructor
representa aGadget
função. Nós escrevemostoy.constructor.prototype
e estamos recebendo{constructor: Gadget}
novamente.Portanto, há um círculo vicioso: você pode usar
toy.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype.constructor.prototype
e sempre seráGadget.prototype
.STH .__ proto__
Enquanto
prototype
é uma propriedade específica para funções,__proto__
está disponível para todos os objetos em que está inseridaObject.prototype
. Refere-se ao protótipo de uma função que pode criar um objeto.Aqui
toy.__proto__
estáGadget.prototype
. ComoGadget.prototype
é um objeto ({}
) e os objetos são criados com aObject
função (veja o exemplo acima), obtemosObject.prototype
. Este é o objeto mais alto no JavaScript e__proto__
só pode indicarnull
.fonte
Resposta curta:
__proto__
é uma referência àprototype
propriedade do construtor que criou o objeto.Objetos em JavaScript
Um objeto JavaScript é um tipo interno para uma coleção de zero ou mais propriedades. Propriedades são contêineres que contêm outros objetos, valores primitivos ou funções.
Construtores em JavaScript
Funções são objetos regulares (implementados
[[Call]]
nos termos ECMA-262) com a capacidade adicional de serem chamados, mas desempenham outro papel no JavaScript: eles se tornam construtores ( fábricas de objetos) se invocados por meio donew
operador. Os construtores são, portanto, uma analogia grosseira às classes em outros idiomas.Toda função JavaScript é na verdade uma instância do
Function
objeto de função interno que possui uma propriedade especial denominadaprototype
usada para implementar a herança baseada em protótipo e as propriedades compartilhadas. Todo objeto criado por uma função construtora tem uma referência implícita (chamada protótipo ou__proto__
) ao valor de seu construtorprototype
.O construtor
prototype
é uma espécie de blueprint para a construção de objetos, pois todo objeto criado pelo construtor herda uma referência a suaprototype
.A cadeia de protótipos
Um objeto especifica seu protótipo através da propriedade interna
[[Prototype]]
ou__proto__
. O relacionamento do protótipo entre dois objetos é sobre herança: todo objeto pode ter outro objeto como seu protótipo. O protótipo pode ser onull
valor.A cadeia de objetos conectados pela
__proto__
propriedade é chamada de cadeia de protótipo . Quando é feita uma referência a uma propriedade em um objeto, essa referência é à propriedade encontrada no primeiro objeto na cadeia de protótipos que contém uma propriedade com esse nome. A cadeia de protótipos se comporta como se fosse um único objeto.Veja esta imagem (extraída deste blog ):
Sempre que você tenta acessar uma propriedade em um objeto, o JavaScript inicia a busca por ela nesse objeto e continua com seu protótipo, o protótipo do protótipo e assim por diante até que a propriedade seja encontrada ou
__proto__
mantenha o valornull
.Quase todos os objetos são instâncias de
Object
, porqueObject.prototype
é o último em sua cadeia de protótipos. MasObject.prototype
não é um exemplo deObject
porqueObject.prototype.__proto__
detém o valornull
.Você também pode criar um objeto com um
null
protótipo como este:Tal objeto é um mapa melhor (dicionário) de um objeto literal, razão pela qual este padrão é às vezes chamado de dict padrão ( Dict para dicionário).
Nota: os objetos literais criados usando
{}
são instâncias deObject
since({}).__proto__
é uma referência aObject.prototype
.fonte