1. Objeto do prototipo
1.1 contras dos construtores
O JavaScript gera novos objetos por meio de construtores, para que os construtores possam ser considerados como modelos para objetos. As propriedades e métodos do objeto de instância podem ser definidos dentro do construtor.
function gat (nome, cor) {this.name = name; this.color = color;} var cat1 = new Cat ('Big Hair', 'White'); Cat1.name // 'Big Hair'cat1.color //' White 'A função CAT no código acima é um construtor. O atributo de nome e o atributo de cor são definidos internamente. Todos os objetos de instância gerarão esses dois atributos. No entanto, isso é um desperdício de recursos do sistema, porque as propriedades não podem ser compartilhadas entre as instâncias de objetos do mesmo construtor.
function gat (nome, cor) {this.name = name; this.color = cor; this.meow = function () {console.log ('mew, mew, mew ...'); };} var cat1 = new Cat ('Big Hair', 'White'); var cat2 = novo Cat ('ei mao', 'preto'); cat1.meow === Cat2.meow // falseNo código acima, CAT1 e CAT2 são instâncias do mesmo construtor. No entanto, seus métodos MEOW são diferentes, ou seja, toda vez que uma nova instância é criada, um novo método MEOW será criado. Isso não é necessário, nem os recursos do sistema de resíduos, porque todos os métodos de miau são o mesmo comportamento e devem ser compartilhados completamente.
1.2 O papel do atributo de protótipo
Na linguagem JavaScript, cada objeto possui um objeto de protótipo correspondente, chamado de objeto de protótipo. Todas as propriedades e métodos definidos no objeto de protótipo podem ser herdados pelo objeto derivado. Este é o design básico do mecanismo de herança de JavaScript.
Além dessa abordagem, o JavaScript também fornece outra maneira de definir objetos de instância. Sabemos que um construtor é uma função, um objeto e também possui suas próprias propriedades e métodos. Um atributo de protótipo aponta para outro objeto, que geralmente é chamado de objeto de protótipo. Este objeto é muito especial. Desde que as propriedades e métodos definidos possam ser compartilhados por todos os objetos de instância. Ou seja, quando o construtor gera um objeto de instância, um atributo de protótipo é atribuído automaticamente ao objeto de instância.
function animal (nome) {this.name = name;} animal.prototype.color = "branco"; var cat1 = novo animal ('cabelos grandes'); var cat2 = new animal ('erimao'); cat1.color // 'white'cat2.color //' branco 'O código acima adiciona um atributo de cor ao objeto de protótipo do animal construtor. Como resultado, os objetos de instância CAT1 e CAT2 carregam esta propriedade.
Mais particularmente, desde que o objeto de protótipo seja modificado, as alterações serão refletidas imediatamente no objeto de instância.
Animal.prototype.color = "amarelo"; cat1.color // 'Yellow'cat2.color //' amarelo '
O código acima altera o valor do atributo de cor do objeto de protótipo para amarelo e o valor do atributo de cor dos dois objetos de instância mudará imediatamente. Isso ocorre porque o objeto de instância na verdade não possui atributo de cor e todos lêem o atributo de cor do objeto de protótipo. Ou seja, quando o próprio objeto de instância não possui uma determinada propriedade ou método, ele será destinado ao protótipo do objeto do construtor para encontrar a propriedade ou método. Essa é a coisa especial dos objetos de protótipo.
Se o próprio objeto de instância tiver uma determinada propriedade ou método, ele não procurará mais essa propriedade ou método no objeto Prototype.
cat1.color = 'preto'; cat2.color // 'amarelo'animal.prototype.color // "amarelo";
O código acima altera a propriedade de cor do objeto de instância CAT1 para preto, para que ele não precise mais ler a propriedade Color do objeto Prototype e o valor deste último ainda é amarelo.
Em suma, a função do objeto de protótipo é definir as propriedades e métodos compartilhados por todos os objetos de instância, portanto também é chamado de protótipo do objeto de instância, e o objeto de instância pode ser considerado como derivado do objeto protótipo.
Animal.prototype.walk = function () {console.log (this.name + 'está andando.');};O código acima define um método de caminhada no objeto Animal.Protype, que será chamado em todos os objetos de instância animal.
1.3 Cadeia de protótipo
Como todos os objetos no JavaScript possuem construtores, e todos os construtores possuem atributos de protótipo (na verdade todas as funções têm atributos de protótipo), todos os objetos têm seus próprios protótipos de protótipo.
Portanto, as propriedades e métodos de um objeto podem ser definidos em si ou em seu objeto de protótipo (como o método de caminhada no código acima). Como o protótipo em si é um objeto e possui seu próprio protótipo, uma cadeia de protótipo é 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. Como rastreando a raiz da fonte, os objetos na fonte são gerados a partir do construtor de objeto (usando o comando new Object ()); portanto, se você o rastrear camada por camada, o protótipo de todos os objetos pode eventualmente ser rastreado para objeto.prototipo. Então, existe um protótipo para object.prototype? A resposta pode ser sim ou não, porque o protótipo do objeto.Prototype é um nulo sem propriedades e métodos.
Object.getProTypeOf (object.prototype) // null
O código acima indica que o protótipo do objeto.Prototipo é nulo. Como Null não possui propriedades, a cadeia de protótipos termina aqui.
A função da "cadeia do protótipo" é que, ao ler um certo atributo de um objeto, o mecanismo JavaScript procura primeiro os atributos do próprio objeto. Se não puder ser encontrado, procurará seu protótipo. Se ainda não puder ser encontrado, procurará o protótipo do protótipo. E assim por diante, se o objeto.Prototype no nível superior ainda não for encontrado, ele retornará indefinido.
Por exemplo, se o atributo de protótipo de uma função apontar para uma matriz, isso significa que a função pode ser usada como um construtor de matriz, porque os objetos da instância que ele gera podem chamar o método da matriz através do atributo protótipo.
function myarray () {} myArray.prototype = new Array (); myArray.prototype.constructor = myarray; var mineA mina no código acima é um objeto de instância de MyArray. Como a propriedade do protótipo de MyArray aponta para uma matriz, a minha pode chamar métodos de matriz (esses métodos são realmente definidos no objeto protótipo da matriz). Quanto à última linha de expressão de instanceof, sabemos que a instância do operador é usada para comparar se um objeto é uma instância de um construtor e a última linha indica que a minha é uma instância de matriz.
A instância da mina de Array // é equivalente a (Array === MyArray.prototype.Constructor) || (Array === Array.prototype.Constructor) || (Array === Object.prototype.Constructor)
O código acima ilustra a essência do operador da instância, que é comparado com os atributos do construtor de todos os objetos de protótipo do objeto de instância (para a introdução desse atributo, consulte a próxima seção). Enquanto houver um, ele retornará verdadeiro, caso contrário, retornará falsa.
1.4 Atributo do construtor
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 p () {} p.prototype.constructor === p // trueComo o atributo construtor é definido no objeto de protótipo, significa que ele pode ser herdado por todos os objetos de instância.
função p () {} var p = new p (); p.constructor // função p () {} p.constructor === P.Prototype.Constructor // Truep.HasownProperty ('construtor') // falseO código acima indica que P é um objeto de instância do construtor P, mas P em si não possui um atributo construtor, que está realmente lendo o atributo p.prototype.Constructor na cadeia de protótipo.
A função do atributo construtor é distinguir em qual construtor o objeto de protótipo está definido.
função f () {}; var f = new f (); f.constructor === f // truef.constructor === regexp // falseO código acima significa que, usando a propriedade do construtor, é determinado que a função do construtor da variável f é f, não regexp.
2.Object.getPrototypeOf
O object.getPrototypeOf Method retorna o protótipo de um objeto.
// O protótipo do objeto vazio é object.prototypeObject.getPrototypeOf ({}) === Object.Prototype // true // O protótipo da função é function.protyPefunção f () {} object.getProtypef (f) == FUNCTOTPOTYPO // TRUE // de f é f.prototypevar f = new f (); object.getPrototypeOf (f) === f.prototype // true3.Object.Create Método
O método Object.Create é usado para gerar um novo objeto e pode substituir o novo comando. Ele aceita um objeto como um argumento e retorna um novo objeto, que herda completamente as propriedades do primeiro, ou seja, o primeiro se torna o protótipo deste último.
var o1 = {p: 1}; var o2 = object.create (o1); o2.p // 1No código acima, o método Object.Create gera O2 com base no O1. Neste momento, o O1 se torna o protótipo de O2, ou seja, O2 herda todas as propriedades do O1.
O método Object.Create é basicamente equivalente ao código a seguir. Se o navegador antigo não suportar o método Object.Create, você poderá usar o código a seguir para implantá -lo.
if (typeof object.create! == "function") {object.create = function (o) {function f () {} f.prototype = o; retornar novo f (); };}O código acima mostra que o método Object.Create está criando essencialmente um novo construtor F, permitindo que o atributo de protótipo de F aponte para objeto O como o protótipo e, finalmente, retornar uma instância de f, para que a instância possa herdar os atributos de O.
Os novos objetos gerados nas três maneiras a seguir são equivalentes.
var o1 = object.create ({}); var o2 = object.create (object.prototype); var o3 = new object ();Se você deseja gerar um objeto que não herde nenhuma propriedade (como métodos de toques e valueof), você pode definir o objeto.Criar o parâmetro como NULL.
var o = object.create (null); o.valueof () // typeError: objeto [objeto de objeto] não tem método 'valueof'
O código acima indica que, se o protótipo do objeto O for nulo, ele não possui algumas propriedades definidas no objeto.Prototipo, como o método ValueOf.
Ao usar o método Object.Create, um protótipo de objeto deve ser fornecido, caso contrário, um erro será relatado.
Object.Create () // TypeError: o protótipo de objeto pode ser apenas um objeto ou nulo
O novo objeto gerado pelo objeto.Crie o método herda dinamicamente o protótipo. Adicionar ou modificar qualquer método no protótipo refletirá imediatamente sobre o novo objeto.
var o1 = {p: 1}; var o2 = object.create (o1); o1.p = 2; o2.p // 2O código acima indica que a modificação do protótipo de objeto afetará o objeto recém -gerado.
Além do protótipo de objeto, o método Object.Create também pode aceitar um segundo parâmetro, representando o objeto de atributos que descrevem os atributos, que é o mesmo formato que o método do objeto.DefineProperties usado. As propriedades do objeto que ele descreve serão adicionadas ao novo objeto.
var o = object.create (object.prototype, {p1: {value: 123, enumerável: true}, p2: {value: "abc", enumerável: true}}); o.p1 // 123o.p2 // "abc"Como o método Object.Create não usa um construtor, a instância do operador não pode ser usada para determinar qual instância do construtor é o objeto. No momento, você pode usar o seguinte método ISPrototyOF para interpretar qual objeto o protótipo é.
4.IsprototypeOf Method
O método ISProTypeOf é usado para determinar se um objeto é um protótipo de outro objeto.
var o1 = {}; var o2 = object.create (o1); var o3 = object.create (o2); o2.isprototypeof (o3) // trueo1.isprototypeof (o3) // trueO código acima mostra que o ISProtyOF retorna true, desde que um objeto esteja na cadeia de protótipo.
5. Um exemplo simples
var classdemo = function () {// variável privada estática var private_static_var = 'aaaa'; // Método privado estático var private_static_func = function (key) {return key + private_static_var; } // Método privado, a chave é passar nesse var private_func = function (self, key) {return private_static_func (key + self.id); } var _class = function (id) {// construtor this.id = id; // public variável} // public métod_class.prototype.public_func = function (key) {return private_func (this, chave); } return _class;} (); var a = new ClassDemo ('Hello World'); alert (a.public_func ('mundo hello'));Não existe uma maneira simples de implementar variáveis privadas e variáveis/métodos estáticos públicos, mas o encapsulamento é suficiente para ser feito nessa medida.