Em uma linguagem típica orientada a objetos, como Java, existe o conceito de classe. Classe é o modelo de um objeto e um objeto é uma instância de uma classe. No entanto, no sistema de linguagem JavaScript, não há conceito de classe. O JavaScript não é baseado em 'classe', mas é implementado por meio de construtores e cadeias de protótipo. No entanto, o ES6 fornece um método de escrita mais próximo dos idiomas tradicionais, introduzindo o conceito de classe (classe) como modelo de objeto. Através da palavra -chave da classe, você pode definir uma classe. Basicamente, a classe do ES6 pode ser considerada apenas um açúcar de sintaxe. A maioria de suas funções pode ser alcançada pelo ES5. O novo método de escrita de classe torna o objeto protótipo escrito mais claro e mais como a sintaxe de programação orientada a objetos.
De acordo com o meu hábito, darei ao diretório do artigo antes de escrevê -lo.
O conteúdo a seguir será dividido nas seguintes subseções:
1. Uma breve introdução aos construtores
2 contras dos construtores
3. O papel do atributo de protótipo
4. Cadeia de protótipo
5. Atributo do Castrutor
5.1: O papel do atributo construtor
6. Instância do operador
1. Uma breve introdução aos construtores
No meu artigo sobre a estreita relação entre construtores e novos comandos em JavaScript, o conceito e as características dos construtores, os princípios e o uso de novos comandos, etc., são introduzidos em detalhes. Se você não estiver familiarizado com os construtores, pode ir e saboreá -los com cuidado. Aqui está uma revisão simples.
O chamado construtor é uma função que fornece um modelo para gerar um objeto e descreve a estrutura básica do objeto. Um construtor pode gerar vários objetos, cada um com a mesma estrutura. Em geral, um construtor é um modelo para um objeto e um objeto é uma instância de um construtor.
As características do construtor são:
R: A primeira letra do nome da função do construtor deve ser capitalizada.
B: Use este objeto internamente para apontar para a instância do objeto a ser gerada.
C: Use o novo operador para ligar para o construtor e retornar a instância do objeto.
Vamos ver o exemplo mais simples.
function pessoa () {this.name = 'keith';} var boy = new pessoa (); console.log (boy.name); // 'keith'2 contras dos construtores
Todos os objetos de instância podem herdar propriedades e métodos no construtor. No entanto, as propriedades não podem ser compartilhadas entre as mesmas instâncias de objeto.
função pessoa (nome, altura) {this.name = name; this.Height = altura; this.hobby = function () {return 'assistindo filmes';}} var boy = new Pessoa ('Keith', 180); var menina = nova pessoa ('rascal', 153); console.log (boy.name); // 'keith' console.log (garota.name); // 'rascal' console.log (boy.hobby === Girl.hobby); //falsoNo código acima, uma pessoa construtora gera duas instâncias de objetos, garoto e menina, e tem duas propriedades e um método. No entanto, seu método de hobby é diferente. Ou seja, sempre que você usar o novo para chamar o construtor para devolvê -lo a uma instância do objeto, um método de hobby será criado. Isso não é necessário nem desperdício de recursos, porque todos os métodos de hobby são comportamentos infantis e podem ser completamente compartilhados por duas instâncias de objetos.
Portanto, a desvantagem dos construtores é que propriedades ou métodos não podem ser compartilhados entre as instâncias de objetos do mesmo construtor.
3. O papel do atributo de protótipo
Para resolver a desvantagem de não ser capaz de compartilhar propriedades entre instâncias de objetos dos construtores, o JS fornece atributos de protótipo.
Cada tipo de dados no JS é um objeto (exceto nulo e indefinido), e cada objeto herda de outro objeto, este último é chamado de objeto "protótipo", exceto o NULL, que não possui seu próprio objeto de protótipo.
Todas as propriedades e métodos no objeto de protótipo serão compartilhados pela instância do objeto.
Quando uma instância do objeto é gerada através de um construtor, o protótipo da instância do objeto é apontado para a propriedade do protótipo do construtor. Cada construtor possui um atributo de protótipo, que é o objeto de protótipo da instância do objeto.
função pessoa (nome, altura) {this.name = name; this.Height = altura; } Pessoa.prototype.hobby = function () {return 'assistindo filmes'; } var boy = nova pessoa ('Keith', 180); var menina = nova pessoa ('rascal', 153); console.log (boy.name); // 'keith' console.log (garota.name); // 'rascal' console.log (boy.hobby === Girl.hobby); //verdadeiroNo código acima, se o método de hobby for colocado no objeto de protótipo, ambos os objetos de instância compartilham o mesmo método. Espero que todos possam entender que, para os construtores, o protótipo é uma propriedade como construtor; Para instâncias de objetos, o protótipo é um protótipo objeto de instâncias de objeto. Portanto, o protótipo é uma propriedade e um objeto.
Objetos de protótipo não são propriedades das instâncias de objetos. Os atributos de uma instância de objeto são atributos herdados da definição do construtor, porque existe uma palavra -chave dentro do construtor para apontar para a instância do objeto a ser gerada. As propriedades de uma instância de objeto são realmente atributos definidos internamente pelo construtor. Enquanto as propriedades e métodos no objeto protótipo forem modificados, as alterações serão refletidas imediatamente em todas as instâncias do objeto.
Pessoa.Prototype.hobby = function () {return 'Swimming'; } console.log (boy.hobby === Girl.Hobby); // True Console.log (boy.hobby ()); // 'Swimming'Console.log (Girl.Hobby ()); //'natação'No código acima, depois de modificar o método de hobby do objeto de protótipo, ambas as instâncias do objeto mudaram. Isso ocorre porque as instâncias do objeto na verdade não têm métodos de hobby, são todos métodos de hobby que lêem objetos de protótipo. Ou seja, quando uma instância do objeto não possui a propriedade e o método, ele pesquisará no objeto Prototype. Se o próprio objeto de instância tiver uma determinada propriedade ou método, ele não será pesquisado no objeto de protótipo.
Boy.Hobby = function () {return 'Play Basketball'; } console.log (boy.hobby ()); // 'jogar basquete' console.log (garota.hobby ()); //'natação'No código acima, quando o método de hobby da instância do objeto Boy for modificado, o método de hobby no objeto de protótipo não será herdado. No entanto, a garota ainda herdará o método do objeto de protótipo.
Para resumir:
R: A função de um objeto de protótipo é definir as propriedades e métodos compartilhados por todas as instâncias do objeto.
B: protótipo, para construtores, é uma propriedade; Para instâncias de objetos, é um objeto de protótipo.
4. Correntes de protótipo
As propriedades e métodos de um objeto podem ser definidos em si ou em seu objeto de protótipo. Como o próprio objeto de protótipo é um objeto para objetar instâncias e também possui seu próprio protótipo, uma cadeia de protótipos é formada. Por exemplo, o objeto A é o protótipo do objeto B, o objeto B é o protótipo do objeto C e assim por diante. A parte superior do protótipo de todos os objetos é o objeto.Prototype, ou seja, o objeto apontado pela propriedade do protótipo do construtor de objeto.
Obviamente, o objeto.Prototype também possui seu próprio objeto de protótipo, ou seja, um objeto nulo sem nenhum atributo e métodos, e o objeto nulo não possui seu próprio protótipo.
1 console.log (object.getProTypeOf (object.prototype)); //nulo
2 Console.log (PERSON.Prototype.isprototypeof (menino)) // true
As características das cadeias de protótipo são:
R: Ao ler uma certa propriedade de um objeto, o mecanismo JavaScript procura primeiro a propriedade do próprio objeto. Se não puder ser encontrado, ele irá para o seu protótipo. Se ainda não puder ser encontrado, ele irá para o protótipo do protótipo. Se o objeto.Prototype no nível superior ainda não for encontrado, indefinido será retornado.
B: Se o próprio objeto e seu protótipo definirem um atributo com o mesmo nome, os atributos do objeto em si serão lidos primeiro, o que é chamado de "substituição".
C: Procurando um determinado atributo no nível da cadeia de protótipo para cima tem um impacto no desempenho. Quanto maior o nível do objeto de protótipo que você está procurando, maior o impacto no desempenho. Se você procurar uma propriedade inexistente, ela atravessará toda a cadeia de protótipo.
Pode ser obscuro olhar para o conceito, vamos dar um exemplo. Mas é realmente importante entender o conceito.
var arr = [1,2,3]; console.log (arr.length); //3console.log (arr.valueof ()) // [1,2,3] console.log (arr.join ('|')) // 1 | 2 | 3No código acima, uma matriz ARR é definida, com três elementos na matriz. Não adicionamos nenhum atributo ou métodos à matriz, mas não relatamos um erro ao ligar para o comprimento, ingressar () e valueof ().
O atributo de comprimento é herdado do Array.Prototype e pertence a uma propriedade no objeto Prototype. O método de junção também é herdado do Array.Prototype e pertence a um método no objeto de protótipo. Esses dois métodos são compartilhados por todas as matrizes. Quando não houver atributo de comprimento no objeto de instância, o objeto de protótipo será pesquisado.
O método Valueof é herdado do object.prototype. Primeiro de tudo, a matriz ARR não possui um método ValueOf; portanto, procure o protótipo objeto Array.prototype. Então, descobri que não há valor do método no objeto ARRAY.Prototype. Por fim, procure o objeto.Prototype.
Vamos dar uma olhada nas propriedades e métodos do objeto ARRAY.Prototype e o objeto.Prototype, respectivamente.
console.log(Object.getOwnPropertyNames(Array.prototype))//["length", "toSource", "toString", "toLocaleString", "join", "reverse", "sort", "push", "pop", "shift", "unshift", "splice", "concat", "slice", "lastIndexOf", "indexOf", "forEach", "map", "filter", "reduceRight", "some", "every", "find", "findIndex", "copyWithin", "fill", "entries", "keys", "keys", "values", "includes", "constructor", "$set", "$remove"] console.log(Object.getOwnPropertyNames(Object.prototype)) // ["toSource", "toString", "toLocaleString", "valueOf", "watch", "unwatch", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "__proto__", "constructor"]
Acredito que, quando você vê isso, você ainda tem um pequeno entendimento do protótipo. Isso é normal. Afinal, é um conceito mais importante e abstrato em JS. É impossível dominá -lo tão rapidamente. Se você comeu mais alguns artigos, poderá dominar a essência. De certa forma, há um exemplo vivo, que também pode ser um problema que todos encontrarão. Você pode dar uma olhada nos objetos JS Construtor e Prototype.
5. Atributo do Castrutor
O objeto de protótipo possui um atributo construtor que aponta para a função do construtor em que o objeto de protótipo está localizado por padrão.
função a () {}; console.log (A.Prototype.Constructor === A) // trueDeve -se notar que o protótipo é propriedade do construtor, e o construtor é o objeto apontado pela propriedade do protótipo do construtor, ou seja, propriedade do objeto do protótipo. Tenha cuidado para não confundir.
console.log (A.HasownProperty ('protótipo')); // True Console.log (A.Prototype.HasownProperty ('Construtor'); //verdadeiroComo o atributo construtor é definido no objeto de protótipo, significa que ele pode ser herdado por todos os objetos de instância.
função a () {}; var a = novo a (); console.log (A.Constructor); //A()console.log(a.Constructor==A.Prototype.Constructor) ;//TrueNo código acima, A é um objeto de instância do construtor A, mas um em si não possui um atributo construtor, que está realmente lendo a cadeia de protótipo.
A.Prototype.Constructor Property.
5.1: O papel do atributo construtor
R: determinar qual função do construtor é o objeto de protótipo pertencente a
função a () {}; var a = novo a (); console.log (a.constructor === a) // true Console.log (a.constructor === Array) // falseO código acima significa que, usando a propriedade do construtor, é determinado que a função construtora do objeto de instância a é a, não a matriz.
B: Crie outra instância a partir da instância
função a () {}; var a = novo a (); var b = new a.constructor (); console.log (B instância de a); //verdadeiroNo código acima, A é um objeto de instância do construtor A, e o construtor pode ser indiretamente chamado de A.Constructor.
C: É possível chamar seu próprio construtor
A.prototype.hello = function () {return new this.constructor (); }D: fornece um padrão de herdar outro construtor de um construtor
function father () {} função filho () {son.height.constructor.call (this); } Filho.Eight = novo pai ();No código acima, pai e filho são construtores. Chamar o pai neste filho dentro formará o efeito do filho herdando o pai.
E: Como o atributo construtor é uma relação entre um objeto de protótipo e um construtor, ao modificar o objeto de protótipo, você deve prestar atenção ao problema apontador do construtor.
Existem duas soluções: aponte o atributo do construtor para a função original do construtor ou apenas adicione propriedades e métodos ao objeto protótipo para evitar a instância da distorção.
6. Instância do operador
A instância do operador retorna um valor booleano indicando se o objeto especificado é uma instância de um construtor.
função a () {}; var a = new a (); console.log (uma instância de a); //verdadeiroComo a instância do é válida para objetos em toda a cadeia de protótipo, o mesmo objeto de instância pode retornar true para vários construtores.
função a () {}; var a = novo a (); console.log (uma instância de a); //truEconsole.log(a instância do objeto); //verdadeiroObserve que a instância dos objetos pode ser usada apenas para tipos de dados complexos (matrizes, objetos etc.) e não podem ser usados para tipos de dados simples (valores booleanos, números, strings etc.).
var x = [1]; var o = {}; var b = true; var c = 'string'; console.log (X instayof Array); //truEconsole.log(o Instância de objeto); // True Console.log (B instanceof boolean); //falseconsole.log(c instanceof string); //falsoAlém disso, nem nulos nem indefinidos são objetos; portanto, a instância de sempre retorna falsa.
console.log (objeto null de objeto); // false Console.log (instância indefinida do objeto); //falso
Usando a instância do operador, você também pode resolver inteligentemente o problema de esquecer de adicionar novo comando ao chamar o construtor.
função keith (nome, altura) {if (! Esta instância de keith) {retorna new Keith (nome, altura); } this.name = nome; this.Height = altura;}No código acima, a instância do operador é usada para determinar se a palavra -chave na função corporal aponta para uma instância do construtor Keith. Caso contrário, significa que o novo comando é esquecido. No momento, o construtor retornará uma instância do objeto para evitar resultados inesperados.
Devido a limitações de espaço, vou apresentá -lo aqui por enquanto.
Na minha próxima participação, falarei sobre alguns métodos nativos de protótipo objetos, como object.getProTypeOf (), object.SetPrototypeof (), etc., e introduzirá uma comparação de métodos para obter objetos nativos.
O exposto acima é a explicação detalhada do atributo de protótipo (recomendado) no JavaScript introduzido pelo editor. Espero que seja útil para você.