JavaScript usa herança prototípica por padrão. Embora não exista o conceito de classe, sua função pode atuar como construtora. O construtor combinado com this e new pode construir uma classe semelhante a Java. Portanto, o JavaScript pode emular a herança baseada em classes estendendo-se.
JavaScript, como outras linguagens orientadas a objetos, usa referências para tipos de objetos. A variável que contém o objeto é apenas um endereço, enquanto o tipo básico de dados é o valor. Ao armazenar objetos em protótipos, pode haver algumas armadilhas.
Vejamos primeiro o primeiro exemplo
Copie o código do código da seguinte forma:
var criar = função() {
função Fn() {}
função de retorno(pai) {
Fn.prototype = pai
retornar novo Fn
}
}()
var pai = {
nome: 'Jack',
idade: 30,
é casado: falso
}
var filho = criar(pai)
console.log(filho)
A função da ferramenta create implementa uma herança de protótipo básica. Cada vez que create é chamado, um novo objeto será copiado com base no objeto pai. Todas as propriedades do novo objeto vêm do pai. Aqui, pai tem três atributos, todos tipos de dados básicos: string, número e booleano.
Agora modifique o filho para ver se isso afetará o pai.
Copie o código do código da seguinte forma:
filho.nome = 'lírio'
criança.idade = 20,
filho.isMarried = verdadeiro
console.log(filho)
console.log(pai)
Os resultados são os seguintes
Ou seja, modificar o filho não afetará o pai.
Vejamos outro exemplo
Copie o código do código da seguinte forma:
var criar = função() {
função Fn() {}
função de retorno(pai) {
Fn.prototype = pai
retornar novo Fn
}
}()
var pai = {
dados: {
nome: 'Jack',
idade: 30,
é casado: falso
},
idioma: ['Java']
}
var filho = criar(pai)
filho.data.name = 'lírio'
filho.dados.idade = 20
filho.data.isMarried = verdadeiro
filho.idioma.push('javascript')
console.dir(filho)
console.dir(pai)
Observe que os dois atributos de pai aqui, dados e idioma, são tipos de referência, um é um objeto e o outro é um array. O filho ainda herda do pai e, em seguida, o filho é modificado. Os resultados são os seguintes.
Como você pode ver, o pai também foi modificado neste momento, e o nome, a idade, etc. do filho são os mesmos. Isso é algo que você deve estar ciente ao usar herança prototípica.
Uma maneira melhor de usar herança é:
1. Os atributos de dados adotam herança de classe (dependendo disso), para que também possam ser configurados por meio de parâmetros quando novos
2. O método adota herança prototípica, que pode economizar memória. Ao mesmo tempo, a substituição de métodos por subclasses não afetará a classe pai.
A seguir está uma função de ferramenta de escrita que satisfaz os dois pontos acima.
Copie o código do código da seguinte forma:
/**
* @param {String} nomedaclasse
* @param {String/Função} superCls
* @param {Função} fábrica
*/
function $class(nome, superClasse, fábrica) {
if (superClasse === '') superClasse = Objeto
functionclazz() {
if (typeof this.init === 'função') {
this.init.apply(isto, argumentos)
}
}
var p = clazz.prototype = novos superCls
clazz.prototype.constructor = clazz
clazz.prototype.className=className
var supr = superCls.prototype
janela[className] = clazz
fábrica.call(p, supr)
}
Ao colocar um tipo de objeto no protótipo de uma classe pai, tome cuidado quando as subclasses o modificarem. Nesse caso, todas as instâncias de subclasses que herdam da classe pai serão modificadas. E os bugs causados por isso são muito difíceis de encontrar.
Uma nova API foi adicionada ao ES5 para implementar a herança prototípica: Object.create. Você pode usá-lo para substituir a função de criação auto-implementada acima, como segue
Copie o código do código da seguinte forma:
var pai = {
nome: 'Jack',
idade: 30,
é casado: falso
}
var filho = Object.create(pai)
console.log(filho)