Extension Method:

  • É syntax sugar para um método estático
  • É algo isolado do objeto
  • Não tem acesso ao objeto todo
  • Só é acessível se ele estiver em um namespace que está importado
  • Não participa de herança
  • É garantido em tempo de compilação

Prototype:

  • É syntax sugar para um método normal, como são todos os métodos de JS
  • Passa fazer parte do objeto
  • Acessa todo o objeto
  • Ele é carregado em toda a vida do objeto
  • Objetos filhos deste também terão o método novo
  • Pode dar erro achando que ele está presente mas não está

Então é similiar, mas completamente diferente.


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente (não vendo nada, é retribuição na minha aposentadoria) (links aqui no perfil também).

Só um pontinho. Nada a discordar, mas acrescentar. Quando crio uma extension method, eu sempre procuro adicionar ao global.using, então não está errado, porém acho que é de bom tom, quando vocêr quer algo que tenha comportamento nativo do Tipo(acho que entendeu), ser importado globalmente.

Quanto a prototype, não tenho muito mais informação a agregar pois conheço pouco, apenas para o que utilizei e por isso também que senti uma similaridade no comportamento que queria ter em js, que tenho em C#.

Obrigado, por agregar ao post!

> *senti uma similaridade no comportamento* A similaridade é apenas na forma como vc usa o método, ou seja, chamando `objeto.novoMetodo()`, como se o `novoMetodo` fosse realmente um método de `objeto`. Mas por baixo dos panos, o mecanismo é completamente diferente. Em C#, vc apenas **tem a impressão** que o método foi criado na classe em questão. Mas é só um _syntax sugar_ para a chamada do método estático: no seu exemplo, `text.log()` é automaticamente convertida para `InjectString.log(text)`. Mas a classe `string` permanece inalterada, nenhum método foi realmente adicionado nela. Por outro lado, em JavaScript, vc realmente está alterando a estrutura do objeto. O método passa a fazer parte dele, e inclusive é herdado pelos objetos filhos. E tem que tomar cuidado ao adicionar coisas no protótipo, principalmente se vc usa `for..in` para iterar. Por exemplo, este código: ```javascript Array.prototype.novaFuncao = function() { // faz algo }; var array = ['a', 'b']; for (var i in array) { console.log(`${i} -> ${array[i]}`); } ``` A saída é: ```none 0 -> a 1 -> b novaFuncao -> function() { // faz algo } ``` Isso porque `for..in` também traz as propriedades que estão no protótipo do objeto, mas nem sempre pode ser o que vc quer ao iterar por ele. Então tem que [tomar alguns cuidados](https://pt.stackoverflow.com/q/449732/112052) para evitar o *prototype pollution*. --- # Não é exclusivo dessas linguagens Vale lembrar que isso também existe em outras linguagens. Por exemplo, em Ruby vc pode modificar qualquer classe: ```ruby # Supondo que UmaClasseQualquer já exista, eu posso adicionar novos métodos nela class UmaClasseQualquer def novoMetodo(x) # faz algo end end ``` E neste caso, vc está de fato adicionando um novo método na classe. Inclusive, dá pra mudar até as classes mais básicas do sistema (embora não seja recomendado): ```ruby # Em Ruby, posso fazer isso. # Assim, todas as somas entre números inteiros dará o mesmo resultado class Integer def +(other) 42 end end # todas as expressões abaixo resultam em 42 puts 10 + 20 puts 2 + 2 puts 10000 + 2000000 ``` Em Python também dá pra fazer algo similar: ```python class UmaClasseQualquer: # métodos da classe, etc ################## # criar uma função qualquer def func(self, param): print(f'novo método: {param}') # adicioná-lo como método de uma classe já existente UmaClasseQualquer.novoMetodo = func x = UmaClasseQualquer() x.novoMetodo(42) # novo método: 42 ``` Mas diferente de Ruby, não dá para fazer com as classes nativas (como `int` ou `str`).
Na verdade quando a *feature* foi criada, a recomendação geral oficial era não colocar no `System` ou algo semelhante. Colocar global tende a ser pior ainda. Claro que para tudo tem exceção, mas para usar a exceção precisa dominar muito bem todas as consequências de usar isto, o que em projetos grandes pode ser um problema. Em JS é bem tranquilo porque é uma linguagem criada para pequenos *scripts*. As pessoas usam para projetos maiores por escolherem a ferramenta errada porque está todo mundo usando, que é o que chamamos de "modinha".