JavaScript: Class.method vs. Class.prototype.method

Qual é a diferença entre as duas declarações seguintes?

Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ } 

Não há problema em pensar na primeira instrução como uma declaração de um método estático e na segunda instrução como uma declaração de um método de instância?

    Sim, a primeira function não tem relação com uma instância de object dessa function de construtor , você pode considerá-la como um ‘método estático’ .

    Em JavaScript funções são objects de primeira class , isso significa que você pode tratá-los como qualquer object, neste caso, você está apenas adicionando uma propriedade ao object de function .

    A segunda function, como você está estendendo o protótipo da function construtora, estará disponível para todas as instâncias de objects criadas com a new palavra-chave, e o contexto dentro dessa function (a palavra this chave this ) se referirá à instância real do object onde você a chama .

    Considere este exemplo:

     // constructor function function MyClass () { var privateVariable; // private member only available within the constructor fn this.privilegedMethod = function () { // it can access private members //.. }; } // A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instance MyClass.staticMethod = function () {}; MyClass.prototype.publicMethod = function () { // the 'this' keyword refers to the object instance // you can access only 'privileged' and 'public' members }; var myObj = new MyClass(); // new object instance myObj.publicMethod(); MyClass.staticMethod(); 

    Quando você cria mais de uma instância de MyClass, você ainda terá apenas uma instância de publicMethod na memory, mas no caso de privilegedMethod, você acabará criando muitas instâncias e staticMethod não terá nenhum relacionamento com uma instância de object.

    É por isso que os protótipos economizam memory.

    Além disso, se você alterar as propriedades do object pai, a propriedade correspondente da criança não tiver sido alterada, ela será atualizada.

    Para aprendizes visuais, ao definir a function sem .prototype

     ExampleClass = function(){}; ExampleClass.method = function(customString){ console.log((customString !== undefined)? customString : "called from func def.");} ExampleClass.method(); // >> output: `called from func def.` var someInstance = new ExampleClass(); someInstance.method('Called from instance'); // >> error! `someInstance.method is not a function` 

    Com o mesmo código, se .prototype for adicionado,

     ExampleClass.prototype.method = function(customString){ console.log((customString !== undefined)? customString : "called from func def.");} ExampleClass.method(); // > error! `ExampleClass.method is not a function.` var someInstance = new ExampleClass(); someInstance.method('Called from instance'); // > output: `Called from instance` 

    Para tornar mais claro,

     ExampleClass = function(){}; ExampleClass.directM = function(){} //M for method ExampleClass.prototype.protoM = function(){} var instanceOfExample = new ExampleClass(); ExampleClass.directM(); ✓ works instanceOfExample.directM(); x Error! ExampleClass.protoM(); x Error! instanceOfExample.protoM(); ✓ works 

    **** Nota para o exemplo acima, someInstance.method () não será executado como,
    ExampleClass.method () causa erro e a execução não pode continuar.
    Mas, por uma questão de ilustração e compreensão fácil, mantive esta sequência. ****

    Resultados gerados a partir do chrome developer console do chrome developer console e do JS Bin
    Clique no link jsbin acima para percorrer o código.
    Alternar seção comentada com ctrl + /

    Sim, o primeiro é um static method também chamado de class method , enquanto o segundo é um instance method .

    Considere os exemplos a seguir para entendê-lo em mais detalhes.

    No ES5

     function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } Person.isPerson = function(obj) { return obj.constructor === Person; } Person.prototype.sayHi = function() { return "Hi " + this.firstName; } 

    No código acima, isPerson é um método estático, enquanto sayHi é um método de instância de Person .

    Abaixo, é como criar um object do construtor Person .

    var aminu = new Person("Aminu", "Abubakar");

    Usando o método estático isPerson .

    Person.isPerson(aminu); // will return true

    Usando o método de instância sayHi .

    aminu.sayHi(); // will return "Hi Aminu"

    No ES6

     class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } static isPerson(obj) { return obj.constructor === Person; } sayHi() { return `Hi ${this.firstName}`; } } 

    Veja como a palavra-chave static foi usada para declarar o método estático isPerson .

    Para criar um object da class Person .

    const aminu = new Person("Aminu", "Abubakar");

    Usando o método estático isPerson .

    Person.isPerson(aminu); // will return true

    Usando o método de instância sayHi .

    aminu.sayHi(); // will return "Hi Aminu"

    NOTA: Os dois exemplos são essencialmente os mesmos, o JavaScript continua sendo uma linguagem sem classs. A class introduzida no ES6 é primariamente um açúcar sintático sobre o modelo de inheritance baseado em protótipo existente.