Синтаксис ООП javascript и объект, который является одновременно var и функцией - PullRequest
1 голос
/ 03 февраля 2012

Это связано с вопросом, который я задал ранее здесь: Как реализовать цепочечные вызовы методов, такие как jQuery?

Я уже некоторое время использую метод из контрольного ответа, и он работает хорошо. Но я бы хотел еще больше изменить синтаксис моего инструментария.

  1. foo(firstarg).bar(secondarg); // should function as the question above.

  2. foo(onlyarg).bar // a function with one argument

  3. foo.bar(onlyarg); // should also work, when a first argument is not appropriate.

  4. foo.bar; // a function without an argument, or returns a static value.

Мне бы хотелось, чтобы все 4 синтаксиса работали с одним и тем же объектом foo, но для этого не хватает понимания ООП. Я попробовал несколько вещей, и до сих пор я могу заставить 1 и 2 работать, а 3 и 4 - работать, но не для всех вместе. Также было бы хорошо, если бы цепочка оставалась опцией, если бы каждая функция возвращала корневой объект.

Редактировать: мне явно нужно быть более конкретным, вот что у меня сейчас:

 var main = function(obj){ this.obj = obj; };
 var tool = function(obj){ return new main(obj); };
 main.prototype = {
      alertThisPlus : function(plus){
           alert(this.obj + ' ' + plus);    
      },
      alertJustThis : function(){
           return alert(this.obj);
      }
 };

использование

 tool('hello').alertThisPlus('world'); // returns alert('hello world')
 tool().alertJustThis('hello world');  // returns alert('hello world');

я хотел бы сделать это:

 tool('hello').alertThisPlus('world'); // returns alert('hello world') no change
 tool.alertJustThis('hello world');  // returns alert('hello world') does not work

Ответы [ 2 ]

3 голосов
/ 04 февраля 2012

Функции - это просто объекты, поэтому вы можете добавлять функции в «инструмент». Вы можете сделать это вручную:

tool.foobar = function() {}; 

Или, если ваши классы структурированы надлежащим образом, вы можете использовать смешанный подход. Примерно так:

function Tool(prefix) {
  this.prefix = prefix;
}

Tool.prototype.alertThisPlus = function(suffix) {
  alert((typeof this.prefix != 'undefined' ? this.prefix + ' ' : '') + suffix);
};

Tool.prototype.alertJustThis = function(msg) {
  alert(msg);
};

function tool(prefix) {
  return new Tool(prefix);
}

// Mix-in the methods from a static instance of Tool onto the 'tool' function.
// This makes both tool.alertThisPlus() and tool.alertJustThis() available,
// both will be called in the context of 'staticTool'.
(function() {
  var staticTool = new Tool();
  for (var o in staticTool) {
    if (typeof staticTool[o] == 'function') {
      tool[o] = staticTool[o].bind(staticTool);
    }
  }
})();

tool('hello').alertThisPlus('world'); // returns alert('hello world')
tool().alertJustThis('hello world');  // returns alert('hello world')
tool.alertJustThis('hello world');    // returns alert('hello world')
0 голосов
/ 03 февраля 2012

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

var foo = (function() {
  alert('foo called');
})();

Сделав еще один шаг, скажем, вы используете некоторые замыкания для возврата значений.

var foo = (function() {
  return {
    bar: "arf arf said the dog"
  }
})();

Теперь вы можете использовать:

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