Класс против статического метода в JavaScript - PullRequest
249 голосов
/ 08 октября 2011

Я знаю, что это будет работать:

function Foo() {};
Foo.prototype.talk = function () {
    alert('hello~\n');
};

var a = new Foo;
a.talk(); // 'hello~\n'

Но если я хочу позвонить

Foo.talk() // this will not work
Foo.prototype.talk() // this works correctly

, я найду несколько способов заставить Foo.talk работать,

  1. Foo.__proto__ = Foo.prototype
  2. Foo.talk = Foo.prototype.talk

Есть ли другие способы сделать это?Я не знаю, правильно ли это делать.Используете ли вы методы класса или статические методы в вашем коде JavaScript?

Ответы [ 14 ]

0 голосов
/ 08 июня 2019

Javascript не имеет реальных классов, скорее он использует систему наследования прототипов, в которой объекты «наследуются» от других объектов через их цепочку прототипов.Это лучше всего объяснить с помощью самого кода:

function Foo() {};
// creates a new function object

Foo.prototype.talk = function () {
    console.log('hello~\n');
};
// put a new function (object) on the prototype (object) of the Foo function object

var a = new Foo;
// When foo is created using the new keyword it automatically has a reference 
// to the prototype property of the Foo function

// We can show this with the following code
console.log(Object.getPrototypeOf(a) === Foo.prototype); 

a.talk(); // 'hello~\n'
// When the talk method is invoked it will first look on the object a for the talk method,
// when this is not present it will look on the prototype of a (i.e. Foo.prototype)

// When you want to call
// Foo.talk();
// this will not work because you haven't put the talk() property on the Foo
// function object. Rather it is located on the prototype property of Foo.

// We could make it work like this:
Foo.sayhi = function () {
    console.log('hello there');
};

Foo.sayhi();
// This works now. However it will not be present on the prototype chain 
// of objects we create out of Foo
0 голосов
/ 20 апреля 2018

Статические вызовы методов осуществляются непосредственно в классе и не могут вызываться в экземплярах класса.Статические методы часто используются для создания служебной функции

Довольно четкое описание

Взято непосредственно с mozilla.org

Foo должен быть привязан к вашему классуЗатем, когда вы создаете новый экземпляр, вы можете вызвать myNewInstance.foo (). Если вы импортируете свой класс, вы можете вызвать статический метод

0 голосов
/ 27 сентября 2017

Когда я столкнулся с такой ситуацией, я сделал что-то вроде этого:

Logger = {
    info: function (message, tag) {
        var fullMessage = '';        
        fullMessage = this._getFormatedMessage(message, tag);
        if (loggerEnabled) {
            console.log(fullMessage);
        }
    },
    warning: function (message, tag) {
        var fullMessage = '';
        fullMessage = this._getFormatedMessage(message, tag);
        if (loggerEnabled) {
            console.warn(fullMessage);`enter code here`
        }
    },
    _getFormatedMessage: function () {}
};

так что теперь я могу вызвать метод информации как Logger.info("my Msg", "Tag");

0 голосов
/ 25 августа 2017

В вашем случае, если вы хотите Foo.talk():

function Foo() {};
// But use Foo.talk would be inefficient
Foo.talk = function () {
    alert('hello~\n');
};

Foo.talk(); // 'hello~\n'

Но это неэффективный способ реализации, лучше использовать prototype.


Другой способМой путь определен как статический класс:

var Foo = new function() {
  this.talk = function () {
    alert('hello~\n');
    };
};

Foo.talk(); // 'hello~\n'

Выше статического класса не нужно использовать prototype, потому что он будет создан только один раз как статическое использование.

https://github.com/yidas/js-design-patterns/tree/master/class

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...