Chamar método da função Construtora

Fala galera, tudo bem? criei uma função construtora chamada MeuObjeto o qual possui um método chamado ‘falar’. Quando eu tento executar o MeuObjeto.falar() tenho um erro dizendo que a função TypeError: MeuObjeto.falar is not a function. Como eu consigo chamar o método falar através da função construtora igual ocorre em Object.create(), ou por exemplo Array.indexOf()?

function MeuObjeto() {

    this.nome = 'Rafa';

    let idade = 19

     function falar(){

         meuObjeto.apply(this)

        return console.log(`Meu nome é ${this.nome} e tenho ${idade} anos`);

    }

}

Para criar um objeto você precisa usar a palavra chave new.

new MeuObject();

E para acessar um método você pode fazer assim:

function MeuObjeto() {
   ...

   this.falar = function () {
        console.log('Uma mensagem');
   }
}

new MeuObjeto().falar();

Opa, blz sky? então cara, eu sei que é possível chamar a função instanciando um novo objeto. Minha dúvida é como é possivel eu chamar o método da função sem instanciar o objeto. Um exemplo é Array.from(). Array é uma função e from também é uma função…

Algo mais ou menos assim?

function Pessoa(nome) {
  this.nome = nome;
}

Pessoa.hello = function () {
  console.log('Olá, Mundo!');
}

Pessoa.hello();
// Olá, Mundo!
1 curtida

Isso mesmo! mas como isso é possível? e porque eu não consigo adicionar esse método dentro da declaração da função Pessoa? a função hello() é static?

Creio que essa seja a maneira padrão de se declarar métodos estáticos dentro de funções construtoras.

Outra forma de fazer isso é usando classes, eu particularmente acho mais elegante:

class Pessoa {
  constructor(nome) {
    this.nome = nome;
  }

  static hello() {
    console.log('Hello, World!');
  }
}

Pessoa.hello();
// Hello, World!

Mais sobre classes.

Simples: uma função é um objeto como qualquer outro, e como tal, pode ter métodos “acoplados” a ela.


Mas vamos por partes. Primeiro, um objeto qualquer pode ter uma função acoplada a ele:

// um objeto qualquer
let obj = { id: 1, nome: 'Fulano' };
// definir uma propriedade que é uma função
obj.funcao = function() { console.log('oi') };
// chamar a função
obj.funcao(); // oi

Segundo a documentação, funções também são objetos (“Every JavaScript function is actually a Function object”). Então nada impede que eu faça a mesma coisa com uma função:

function Abc() {
    // função que faz algo...
}

Abc.fazOutraCoisa = function(n) {
    console.log(n);
}
Abc.fazOutraCoisa(20); // 20

console.log(typeof Abc); // function

// repare que "fazOutraCoisa" aparece como uma das propriedades de Abc
console.log(Object.getOwnPropertyNames(Abc)); // [ 'length', 'name', 'arguments', 'caller', 'prototype', 'fazOutraCoisa' ]

Repare que não preciso criar uma instância de Abc para usar a função fazOutraCoisa. Pois ela é uma propriedade da própria função Abc. No fundo, isso é uma forma de simular os métodos estáticos de outras linguagens.


Foi falado sobre o class e static para criar o “método estático”. Mas no fundo isso é só um açúcar sintático (uma forma mais “simples/elegante” de se criar a mesma coisa). Pois no fundo, não existem classes de fato no JavaScript, já que o class é no fundo uma outra forma de se criar uma função construtora:

class Abc {
    static fazOutraCoisa(n) {
        console.log(n);
    }
}

console.log(typeof Abc); // function
console.log(Object.getOwnPropertyNames(Abc)); // [ 'length', 'name', 'prototype', 'fazOutraCoisa' ]