Prévia do material em texto
Aula 8 - Herança
1. O encadeamento de protótipos é a base para o mecanismo de herança em
JavaScript, sendo a maioria dos objetos herdeiros em algum nível do
objeto Object.prototype. Qual dos objetos a seguir tem um objeto nulo como
herdeiro?
Resposta: E. obj = {}.__proto__
Justificativa: {}.__proto__ é o próprio Object.prototype e este não tem ancestral,
quando usado como atribuição direta não terá ancestral. Quando usado como parâmetro
para Object.create será o mesmo que Object.create(Object.prototype).
Object.create(Object.prototype) cria um objeto herdeiro direto de Object.prototype.
Object.create({}) cria um objeto herdeiro de outro objeto vazio que, por sua vez, é
herdeiro de Object.prototype.
{} cria um objeto vazio que é herdeiro de Object.prototype.
2. Object.prototype é o principal objeto na herança de protótipos implementada pelo
JavaScript. Com a exceção de alguns poucos objetos, como o null, por exemplo,
a maioria dos demais objetos herda um protótipo, sendo o primeiro deles
o Object.prototype. Isso garante que todos os objetos tenham propriedades e
métodos mínimos necessários para o desenvolvimento do código. Qual dos
métodos a seguir faz parte do Object.prototype?
Resposta: A. toLocaleString
Justificativa: Object.prototype tem um método denominado propertyIsEnumerable e
não apenas isEnumerable. getValue inexiste no protótipo, tendo um similar de
nome valueOf.
create é um método estático do objeto Object, e não do protótipo.
length é uma propriedade do protótipo, e não um método.
toLocaleString é um método que por padrão invoca o método toString e pode ser
sobrescrito pelos herdeiros para permitir customizações da exibição textual de um
objeto.
3. Considerando seus conhecimentos a respeito de herança e do encadeamento de
protótipos, assinale a alternativa que apresenta os valores exibidos pelo código a
seguir:
var objA = { a: 1 }
var objB = { b: 2 }
objB = { __proto__: objA }
console.log(objB.a, objB.b)
var objA = { a: 1 }
var objB = { b: 2 }
objB.__proto__ = objA
console.log(objB.a, objB.b)
Resposta: B.
1 undefined
1 2
Justificativa: Variáveis com var podem ser redeclaradas. Logo, o código não resultaria
em erro, mas no primeiro caso resultaria em um valor indefinido ao tentar acessar a
propriedade b de objB, pois em vez de definir o protótipo sobrescrevendo a
propriedade __proto__ do objeto, ele foi recriado literalmente apenas com ela definida,
eliminando a existência da propriedade b.
https://ultra.content.blackboardcdn.com/ultra/uiv3900.74.0-rel.25_afc4ff2
No segundo caso os valores 1 e 2 seriam impressos o primeiro herdado de objA e o
segundo definido pelo próprio objB.
4. O aplicativo a seguir define um objeto principal e dois herdeiros. Determine qual
das soluções a seguir permite que cada um dos herdeiros implemente seu
próprio método Reiniciar():
var maquina = { id: 0, Reiniciar() }
var computador = { __proto__: maquina, idiomaTeclado: 'PT-BR' }
var tablet = { __proto__: maquina, sensibildadeTouch: 0.7}
Resposta: D.
computador.Reiniciar = () => // expressão
tablet.Reiniciar = () => // expressão
Justificativa: Deve ser criada uma propriedade Reiniciar para cada objeto, tendo o
endereço de uma nova função atribuído a cada uma delas. Para tanto, não se pode
utilizar a terminação Reiniciar(), que seria interpretada como a invocação do método, e
não uma atribuição. Ao tentar fazer essas atribuições em Object.prototype, estaríamos
sobrescrevendo a função de máquina e não haveria como diferenciá-la para cada
objeto. Também não se pode indexar a referência de uma função.
5. Ao sobrescrever o método valueOf de um objeto ou protótipo, sempre que este
precisar ser convertido para um valor primitivo a nova função será chamada. A
partir disso, determine o resultado exibido pelo algoritmo a seguir:
var obj1 = { valor1: 1 }
var obj2 = { valor2: 2, __proto__: obj1 }
var obj3 = { valor3: 3, __proto__: obj2 }
var obj4 = { valor4: 4, __proto__: obj2 }
obj1.valor4 = 2
obj2.valor3 = 3
obj3.valor2 = 4
obj4.valor1 = 5
Object.prototype.valueOf = function()
{
let acum = 0
acum += Number.isFinite(this.valor1) ? this.valor1 : 0
acum += Number.isFinite(this.valor2) ? this.valor2 : 0
acum += Number.isFinite(this.valor3) ? this.valor3 : 0
acum += Number.isFinite(this.valor4) ? this.valor4 : 0
return acum
}
console.log(obj1 - obj2 + obj3 - obj4)
Resposta: A. -9
Justificativa: Primeiramente, é importante destacar a relação de dependência entre os
objetos:
obj1 -> obj2 -> obj3, obj4
Logo, o obj4 não herda nada de obj3.
Inicialmente, se fossem exibidas as propriedades herdadas e não herdadas de todos os
objetos:
obj1 -> { valor1: 1 }
obj2 -> { valor1: 1, valor2: 2 }
obj3 -> { valor1: 1, valor2: 2, valor3: 3 }
obj3 -> { valor1: 1, valor2: 2, valor4: 4 }
Ao adicionar uma propriedade ao obj1:
obj1 -> { valor1: 1, valor4: 2 }
Ao adicionar uma propriedade ao obj2:
obj2 -> { valor1: 1, valor2: 2, valor3: 3, valor4: 2 }
valor4 foi herdado da nova propriedade de obj1
Ao adicionar uma propriedade ao obj3:
obj3 -> { valor1: 1, valor2: 4, valor3: 3, valor4: 2 }
valor4 foi herdado da nova propriedade de obj1 e uma nova propriedade (valor2) é
criada mesmo o protótipo já possuindo uma.
Ao adicionar uma propriedade ao obj4:
obj3 -> { valor1: 5, valor2: 2, valor3: 3, valor4: 4 }
Foi criada uma propriedade valor1 própria com valor diferente de obj1.valor1
O somatório de cada objeto ficará:
obj1 = 3
obj2 = 8
obj3 = 10
obj4 = 14
E o resultado da expressão obj1 - obj2 + obj3 - obj4:
3 - 8 + 10 - 14 = -9