Slide 1

Slide 1 text

JavaScript Orientado a Objetos

Slide 2

Slide 2 text

Um pouco de história

Slide 3

Slide 3 text

Um pouco de história “I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (...)” “OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.”

Slide 4

Slide 4 text

O que falaremos hoje ● Objetos; ● Métodos; ● Classes; ● Interfaces; ● Polimorfismo; ● Recursão aberta; ● Instanciação; ● Herança; ● Encapsulamento. ● Associação; ● Composição; ● Padrões de projeto; ● SOLID; ● GRASP; ● DDD.

Slide 5

Slide 5 text

Objetos { id: 123, nome: 'churros', preço: 2.75, tags: [ 'comidas', 'doces' ] }

Slide 6

Slide 6 text

Objetos 'prop' in obj // false obj.prop = 'foo' // 'foo' obj.prop = 'bar' // 'bar' obj.prop // 'bar' obj['prop'] // 'bar' delete obj.prop // true 'prop' in foo // false

Slide 7

Slide 7 text

Métodos foo.bar = function () { console.log('Uma propriedade de um objeto aceita qualquer valor.') console.log('Inclusive uma função.') console.log('Pode me chamar de método então!') }

Slide 8

Slide 8 text

Interfaces e Polimorfismo var gato = { nome: 'Gato', barulho: function () { console.log('miau') } } var pato = { nome: 'Pato', barulho: function () { console.log('quack!') } } function qualBarulho (animal) { console.log('O ' + animal.nome + ' faz:') animal.barulho() }

Slide 9

Slide 9 text

Interfaces e Polimorfismo O código que acabamos de ver é polimórfico, mas existe um outro aspecto do polimorfismo que é mudar o comportamento da superclasse na subclasse. Deixemos para quando falarmos de herança.

Slide 10

Slide 10 text

Classes Não há!

Slide 11

Slide 11 text

Recursão aberta this ● objeto global em chamadas simples; ● o próprio objeto em métodos; ● o objeto sendo construído em chamadas com new; ● o primeiro parâmetro em call e apply.

Slide 12

Slide 12 text

Recursão aberta function foo () { var bar = function () { return this } console.log('foo: this é ' + this) // global console.log('bar: this é ' + bar()) // global }

Slide 13

Slide 13 text

Recursão aberta var obj = { foo: function () { var bar = function () { return this } console.log('foo: this é ' + this) // obj console.log('bar: this é ' + bar()) // ahn? } }

Slide 14

Slide 14 text

Recursão aberta var obj = { foo: function () { var that = this var bar = function () { return that } console.log('foo: this é ' + this) // obj console.log('bar: this é ' + bar()) // obj :) } }

Slide 15

Slide 15 text

Instanciação var obj = { }

Slide 16

Slide 16 text

Instanciação function criaAnimal (nome, barulho) { return { nome: nome, barulho: barulho } } var pato = criaAnimal('pato', 'quack!') pato.constructor // [Function: Object] function criaAnimal (nome, barulho) { var animal = { } animal.nome = nome animal.barulho = barulho return animal } var pato = criaAnimal('pato', 'quack!') pato.constructor // [Function: Object]

Slide 17

Slide 17 text

Instanciação // é importante iniciar com letra maiúscula! function Animal (nome, barulho) { this.nome = nome this.barulho = barulho } var pato = new Animal('pato', 'quack!') pato.constructor // [Function: Animal] pato instanceof Animal // true

Slide 18

Slide 18 text

Herança prototípica Herança é utilizar a estrutura e o comportamento da superclasse na subclasse. Na herança prototípica não existe distinção entre instância e classe, um objeto qualquer pode ser utilizado como protótipo para criação de outro (objetos estes dividindo um protótipo em comum). Prototípicos são dinâmicos, podemos alterá-los em tempo de execução. Esqueça classes abstratas, sealed, interfaces, etc.

Slide 19

Slide 19 text

Herança prototípica function Animal (nome, barulho) { this.nome = nome this.barulho = barulho } var pato = new Animal('pato', 'quack!') var pato2 = new Animal('pato 2', 'queeeeeeeeeck') 'apresentacao' in pato // false Animal.prototype.apresentacao = function () { console.log('Eu sou ' + this.nome + ' e faço ' + this.barulho) } 'apresentacao' in pato // true pato.hasOwnProperty('apresentacao') // false

Slide 20

Slide 20 text

Herança prototípica __proto__

Slide 21

Slide 21 text

Herança prototípica .constructor.prototype.constructor.prototype.constructor.(...)

Slide 22

Slide 22 text

Herança prototípica function Animal (nome, barulho) { this.nome = nome this.barulho = barulho } Animal.prototype.apresentacao = function () { console.log('Eu sou ' + this.nome + ' e faço ' + this.barulho) } var cao = new Animal('cão', 'auuuu') function Pato (barulho) { Animal.call(this, 'pato', barulho) } Pato.prototype = Object.create(Animal. prototype) Pato.prototype.quack = function () { console.log(this.barulho) } var pato = new Pato('quack!') var pato2 = new Pato('queeeeeeeeeck')

Slide 23

Slide 23 text

Herança prototípica

Slide 24

Slide 24 text

Encapsulamento ● Proteger o estado do objeto do mundo exterior. ● Em JavaScript nosso típico private não existe. “Lots of so called object oriented languages have setters and when you have an setter on an object you turned it back into a data structure.”

Slide 25

Slide 25 text

Encapsulamento // utilizando prefixos function Circulo (diametro) { // convenciona-se que propriedades iniciadas por "_" são privadas // nenhum tratamento especial é feito pela linguagem // funcionam como uma propriedade qualquer this._raio = diametro / 2 }

Slide 26

Slide 26 text

Encapsulamento // utilizando closures function Circulo (diametro) { // enclausuramos o raio apenas a função construtora // e expomos o que for necessário via funções var _raio = diametro / 2 this.setDiametro = function (diametro) { _raio = diametro / 2 } this.getDiametro = function (diametro) { return _raio * 2 } }

Slide 27

Slide 27 text

Encapsulamento // utilizando getters/setters function Circulo(diametro) { this._raio = diametro / 2 } Object.defineProperty( Circulo.prototype, 'diametro', { get: function () { return this._raio * 2 }, set: function(diametro) { this._raio = diametro / 2 } } )

Slide 28

Slide 28 text

Encapsulamento function Circulo (diametro) { this._raio = diametro / 2 } Object.defineProperty( Circulo.prototype, 'PI', { value: 3.1415, enumerable: true, writable: false // apesar de a escrita não gerar erro (é ignorada), funciona como uma constante } )

Slide 29

Slide 29 text

Conclusão JavaScript pegou emprestado conceitos de diversas linguagens de programação. A linguagem é dinâmica não só no que diz a respeito a sua sintaxe ou tipagem, mas também em como OO é feito. Não tente fazer OO da forma clássica, entenda bem como JavaScript funciona e arquitete a solução para sua necessidade. E claro, lembre-se de evitar as más partes!

Slide 30

Slide 30 text

Conclusão JavaScript pegou emprestado conceitos de diversas linguagens de programação. A linguagem é dinâmica não só no que diz a respeito a sua sintaxe ou tipagem, mas também em como OO é feito. Não tente fazer OO da forma clássica, entenda bem como JavaScript funciona e arquitete a solução para sua necessidade. E claro, lembre-se de evitar as más partes!

Slide 31

Slide 31 text

Bônus http://leftoversalad.tumblr.com

Slide 32

Slide 32 text

Bônus

Slide 33

Slide 33 text

Bônus

Slide 34

Slide 34 text

Bônus

Slide 35

Slide 35 text

Bônus

Slide 36

Slide 36 text

Bônus

Slide 37

Slide 37 text

Bônus

Slide 38

Slide 38 text

Bônus

Slide 39

Slide 39 text

Bônus

Slide 40

Slide 40 text

Bônus

Slide 41

Slide 41 text

Bônus

Slide 42

Slide 42 text

Bônus

Slide 43

Slide 43 text

Bônus

Slide 44

Slide 44 text

Bônus