Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Nas Entranhas do JavaScript: Meta Programação

Nas Entranhas do JavaScript: Meta Programação

Talk apresentada no Front In POA 2016.
Nela explico um pouco sobre as features disponíveis em JavaScript para fazermos meta programação e tento apresentar casos de uso reais e exemplos simples.

Lucas Fernandes da Costa

December 10, 2016
Tweet

More Decks by Lucas Fernandes da Costa

Other Decks in Programming

Transcript

  1. META PROGRAMAÇÃO
    NAS ENTRANHAS DO JAVASCRIPT:
    LUCASFCOSTA LFERNANDESCOSTA

    View Slide

  2. O QUE É META
    PROGRAMAÇÃO?

    View Slide

  3. É A CAPACIDADE DE UM
    PROGRAMA LER E
    ALTERAR À SI MESMO OU
    OUTROS EM TEMPO DE
    EXECUÇÃO

    View Slide

  4. SED UT
    PERSPICIATIS UNDE
    OMNIS ISTE NATUS
    ERROR SIT

    View Slide

  5. SED UT
    PERSPICIATIS UNDE
    OMNIS ISTE NATUS
    ERROR SIT
    CHIMARRÃO DA META
    PROGRAMAÇÃO

    View Slide

  6. View Slide

  7. Isso é Meta Programação

    View Slide

  8. Mas não é disso que vamos falar
    Isso é Meta Programação

    View Slide

  9. Mas não é disso que vamos falar
    Isso é Meta Programação
    Meta Level
    JavaScript

    View Slide

  10. Mas não é disso que vamos falar
    Isso é Meta Programação
    Meta Level
    JavaScript
    Base Level
    Java

    View Slide

  11. Reflective Meta
    Programming

    View Slide

  12. Reflective Meta
    Programming
    Introspecção

    View Slide

  13. Reflective Meta
    Programming
    Introspecção
    Auto-modificação

    View Slide

  14. Reflective Meta
    Programming
    Introspecção
    Auto-modificação
    Intercessão

    View Slide

  15. Meta Object Protocol

    View Slide

  16. Meta Object Protocol
    Prevê um vocabulário
    (um protocolo) que define
    como são feitas as
    operações sobre objetos

    View Slide

  17. Meta Object Protocol
    ecma-international.org/ecma-262

    View Slide

  18. Meta Object Protocol
    ecma-international.org/ecma-262

    View Slide

  19. PROPERTY
    DESCRIPTORS

    View Slide

  20. Property Descriptors
    Descrevem
    características de
    propriedades

    View Slide

  21. Property Descriptors
    meuObjeto
    propriedade

    View Slide

  22. Property Descriptors
    meuObjeto
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    propriedade

    View Slide

  23. Indica o valor da propriedade
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  24. Indica se ela será listada por
    funções como Object.keys
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  25. Indica se ela pode ser definida
    com o operador de atribuição (=)
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  26. Indica se o descritor dessa
    propriedade pode ser alterado
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  27. É a função que será invocada
    para acessar a propriedade
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  28. É a função que será invocada ao
    atribuir um valor para a propriedade
    (operador de atribuição)
    value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  29. value enumerable writable configurable get set
    any boolean boolean boolean function function
    Property Descriptors

    View Slide

  30. Getters
    Lazy Properties

    View Slide

  31. Getters
    Lazy Properties
    Propriedades
    calculadas apenas
    quando solicitado

    View Slide

  32. Getters
    Lazy Properties
    cesta
    frutas
    {banana: 1, morango: 1}

    View Slide

  33. Getters
    Lazy Properties
    cesta
    dataNasc
    value: 08/05/1995
    peso
    400
    frutas
    {banana: 1, morango: 1}

    View Slide

  34. Getters
    Lazy Properties
    cesta
    dataNasc
    value: 08/05/1995
    peso
    600
    frutas
    {banana: 2, morango: 1}

    View Slide

  35. Getters
    Lazy Properties
    cesta
    dataNasc
    value: 08/05/1995
    peso
    800
    frutas
    {banana: 3, morango: 1}

    View Slide

  36. Getters
    Lazy Properties
    cesta
    dataNasc
    value: 08/05/1995
    peso
    800
    frutas
    {banana: 3, morango: 1}
    Muitas atribuições ao peso!
    Poucos acessos!

    View Slide

  37. Getters
    Lazy Properties
    cesta
    dataNasc
    value: 08/05/1995
    peso
    get: function
    frutas
    {banana: 1, morango: 1}

    View Slide

  38. Getters
    Lazy Properties
    pessoa
    dataNasc
    value: 08/05/1995
    idade
    get: function
    cesta
    peso
    frutas
    {banana: 1, morango: 1}
    get: function
    cesta.peso

    View Slide

  39. Getters
    Lazy Properties
    pessoa
    dataNasc
    value: 08/05/1995
    idade
    get: function
    pessoa
    dataNasc
    value: 08/05/1995
    idade
    get: function
    cesta
    peso
    frutas
    {banana: 1, morango: 1}
    get: function
    invoca a função get
    cesta.peso

    View Slide

  40. Getters
    Lazy Properties
    pessoa
    dataNasc
    value: 08/05/1995
    invoca a função get
    idade
    get: function
    200
    pessoa
    dataNasc
    value: 08/05/1995
    idade
    get: function
    pessoa
    dataNasc
    value: 08/05/1995
    cesta.peso
    idade
    get: function
    cesta
    peso
    frutas
    {banana: 1, morango: 1}
    get: function

    View Slide

  41. Getters
    APIs Fluídas
    expect('word').to.be.a('string');
    expect([1, 2, 3]).to.have.length(3);

    View Slide

  42. Getters
    APIs Fluídas
    pega.o(chimas).e.adiciona('erva')

    View Slide

  43. Setters
    Múltiplas Atribuições
    pessoa
    nomeCompleto
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''

    View Slide

  44. Setters
    Múltiplas Atribuições
    pessoa
    nomeCompleto
    pessoa.nomeCompleto
    = ‘João Silva'
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''

    View Slide

  45. Setters
    Múltiplas Atribuições
    pessoa
    nomeCompleto
    pessoa.nomeCompleto
    = ‘João Silva'
    invoca a
    função set
    passando
    ‘João Silva’
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''

    View Slide

  46. Setters
    Múltiplas Atribuições
    pessoa
    nomeCompleto
    pessoa.nomeCompleto
    = ‘João Silva'
    invoca a
    função set
    passando
    ‘João Silva’
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''
    pessoa
    nomeCompleto
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''

    View Slide

  47. Setters
    Múltiplas Atribuições
    pessoa
    nomeCompleto
    pessoa.nomeCompleto
    = ‘João Silva'
    invoca a
    função set
    passando
    ‘João Silva’
    set: function
    primeiroNome
    value: ''
    sobrenome
    value: ''
    pessoa
    nomeCompleto
    set: function
    primeiroNome
    value: 'João'
    sobrenome
    value: 'Silva'

    View Slide

  48. SED UT
    PERSPICIATIS UNDE
    OMNIS ISTE NATUS
    ERROR SIT
    *Live coding begins*

    View Slide

  49. PROXIES

    View Slide

  50. O que são Proxies?
    Proxies são wrappers
    que permitem
    interceptar operações

    View Slide

  51. COMPOSIÇÃO DE UM PROXY
    Proxy Wrapper
    handler
    get
    set: function
    set
    set: function
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘Silva'
    Traps

    View Slide

  52. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    const p = new Proxy(target, handler);

    View Slide

  53. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    const p = new Proxy(target, handler);

    View Slide

  54. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    const p = new Proxy(target, handler);

    View Slide

  55. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    const p = new Proxy(target, handler);
    p

    View Slide

  56. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    const p = new Proxy(target, handler);
    p.nome
    Pede a
    propriedade
    ao wrapper

    View Slide

  57. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    const p = new Proxy(target, handler);
    p.nome
    Chama a trap
    get passando
    target e nome
    da propriedade

    View Slide

  58. FUNCIONAMENTO DE UM PROXY
    Proxy Wrapper
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘Silva'
    handler
    get
    function
    set
    function
    const p = new Proxy(target, handler);
    p.nome
    Devolve o
    retorno da
    função da trap
    get

    View Slide

  59. List Comprehensions
    Arrays
    Infinitos

    View Slide

  60. 0 1 2
    0 2 4
    pares[0]
    Arrays
    Infinitos
    Array Infinito
    get
    function

    View Slide

  61. 0 1 2
    0 2 4
    pares[0]
    Arrays
    Infinitos
    Array Infinito
    get
    function

    View Slide

  62. 0 1 2
    0 2 4
    pares[0]
    Arrays
    Infinitos
    Array Infinito
    get
    function

    View Slide

  63. 0 1 2
    0 2 4
    pares[0]
    Arrays
    Infinitos
    Array Infinito
    get
    function

    View Slide

  64. 0 1 2
    0 2 4
    pares[0]
    Arrays
    Infinitos
    Array Infinito
    get
    function

    View Slide

  65. 0 1 2 3
    0 2 4 undefined
    pares[3]
    Arrays
    Infinitos
    Proxy Wrapper
    get
    function

    View Slide

  66. 0 1 2 3
    0 2 4 undefined
    pares[3]
    Arrays
    Infinitos
    Proxy Wrapper
    get
    function

    View Slide

  67. 0 1 2 3
    0 2 4 undefined
    pares[3]
    Arrays
    Infinitos
    Proxy Wrapper
    get
    function

    View Slide

  68. 0 1 2 3
    0 2 4 undefined
    pares[3]
    Arrays
    Infinitos
    Proxy Wrapper
    get
    function
    Calcula o valor que
    deveria estar no índice 3

    View Slide

  69. 0 1 2 3
    0 2 4 undefined
    pares[3]
    Arrays
    Infinitos
    Proxy Wrapper
    get
    function
    Calcula o valor que
    deveria estar no índice 3

    View Slide

  70. Arrays
    Infinitos

    View Slide

  71. Sugestões
    de
    Propriedades
    Indicar ao utilizador
    da API qual a maneira
    correta de utilizá-la

    View Slide

  72. Sugestões
    de
    Propriedades
    pessoa
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function

    View Slide

  73. Sugestões
    de
    Propriedades
    pessoa
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    pessoa.seuNome

    View Slide

  74. Sugestões
    de
    Propriedades
    pessoa
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    pessoa.seuNome

    View Slide

  75. Sugestões
    de
    Propriedades
    pessoa
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    pessoa.seuNome

    View Slide

  76. Sugestões
    de
    Propriedades
    pessoa
    target
    nome
    value: ‘João'
    sobrenome
    value: ‘João'
    handler
    get
    function
    set
    function
    pessoa.seuNome
    Você quis dizer:
    "nome"?

    View Slide

  77. “Refletindo" Operações
    ES6 Reflect

    View Slide

  78. “Refletindo" Operações
    ES6 Reflect
    Reflect.get

    View Slide

  79. “Refletindo" Operações
    ES6 Reflect
    Reflect.get
    Reflect.set

    View Slide

  80. “Refletindo" Operações
    ES6 Reflect
    Reflect.get
    Reflect.set
    Reflect.[[trapName]]

    View Slide

  81. SED UT
    PERSPICIATIS UNDE
    OMNIS ISTE NATUS
    ERROR SIT
    *Live coding begins*

    View Slide

  82. SYMBOLS

    View Slide

  83. O que são symbols?
    Novo tipo primitivo

    View Slide

  84. O que são symbols?
    Novo tipo primitivo
    "Symbols are all about Reflection
    within implementation"
    Keith Cirkel

    View Slide

  85. symbol Symbol
    !==

    View Slide

  86. symbol Symbol
    !==
    Tipo Primitivo

    View Slide

  87. symbol Symbol
    !==
    Tipo Primitivo Objeto Wrapper

    View Slide

  88. symbols
    new Symbol('description')

    View Slide

  89. symbols
    new Symbol('description')

    View Slide

  90. symbols
    new Symbol('description')
    new denota a criação
    de um novo objeto

    View Slide

  91. symbols
    new Symbol('description')
    Symbol('description')
    new denota a criação
    de um novo objeto

    View Slide

  92. symbols
    new Symbol('description')
    Symbol('description')
    new denota a criação
    de um novo objeto
    retorna um
    símbolo (primitivo)

    View Slide

  93. SÍMBOLOS
    PRIMITIVOS SÃO
    ÚNICOS

    View Slide

  94. Um symbol é unico
    Symbol('id') !== Symbol('id')

    View Slide

  95. Um symbol é unico
    Symbol('id') !== Symbol('id')
    Symbol.for('id') === Symbol.for('id')
    Cuidado com o registro global!

    View Slide

  96. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'

    View Slide

  97. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)

    View Slide

  98. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    timestamp
    value: 1481236691

    View Slide

  99. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    timestamp
    value: 1481236691
    Facilmente sobrescrito
    por engano

    View Slide

  100. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'

    View Slide

  101. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)

    View Slide

  102. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    symbol(time)
    value: 1481236691

    View Slide

  103. symbols no mundo real
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    marcaTimestamp(pessoa)
    pessoa
    nome
    value: 'João'
    sobrenome
    value: 'Silva'
    value: 1481236691
    symbol(time)
    nunca haverá conflito!

    View Slide

  104. Símbolos usados para
    dirigir as operações
    nativas da linguagem
    Well Known Symbols

    View Slide

  105. Utilizado por um objeto para
    verificar se outro objeto é
    considerado uma instância sua
    Well Known Symbols
    Symbol.hasInstance

    View Slide

  106. Well Known Symbols
    Symbol.hasInstance
    portoAlegre instanceof lugarTri

    View Slide

  107. Well Known Symbols
    Symbol.hasInstance
    portoAlegre instanceof lugarTri
    lugarTri[Symbol.hasInstance](portoAlegre)

    View Slide

  108. Well Known Symbols

    View Slide

  109. Well Known Symbols
    Symbol.toPrimitive

    View Slide

  110. Well Known Symbols
    Symbol.toPrimitive
    Symbol.toStringTag

    View Slide

  111. Well Known Symbols
    Symbol.toPrimitive
    Symbol.toStringTag
    Symbol.iterator

    View Slide

  112. Well Known Symbols
    Symbol.toPrimitive
    Symbol.toStringTag
    Symbol.iterator
    E muitos mais…

    View Slide

  113. SED UT
    PERSPICIATIS UNDE
    OMNIS ISTE NATUS
    ERROR SIT
    *Live coding begins*

    View Slide

  114. OBRIGADO!
    MUITO MAIS EM LUCASFCOSTA.COM
    LUCASFCOSTA LFERNANDESCOSTA

    View Slide