Создание объекта javascript для эмуляции класса и статических методов? - PullRequest
3 голосов
/ 18 декабря 2009

Может кто-нибудь помочь? У меня есть следующий объект в javascript ... из того, что я понимаю, каждый "INSTANCE" моего календаря будет иметь свои собственные переменные.

Мой вопрос: мне нужно вставить имя метода / функции с именем "InitilizeHolidays", которое необходимо добавить в массив, но детали должны быть одинаковыми во всех случаях ... Я думал о каком-то вызове метода STATIC это возможно ..

Конечно, если я вставлю это в «прототип», оно будет специфичным для каждого экземпляра, и мне нужно, чтобы оно влияло на все экземпляры.

Можно ли инициализировать переменные, которые влияют на ВСЕ экземпляры и ТОЛЬКО конкретные экземпляры? Куда мне их вставить?

Любая помощь действительно ценится

function Calendar() {
    // I presume variables set here are available to "ALL" instances

}

Calendar.prototype = {
    constructor: Calendar,
    getDateTest: function() {
        return "date test";
    },
    getDateTest2: function() {
        return "date test";
    }
};

Ответы [ 3 ]

2 голосов
/ 18 декабря 2009

Что-то смущает наследование прототипов Javascript. Позвольте мне объяснить.

Поля, определенные в объекте-прототипе, совместно используются всеми экземплярами . Проблема в том, что вы не можете заметить это, потому что присваивание в поле объекта o всегда выполняется в экземпляре o, а не в прототипе.

Таким образом, у вас есть два варианта определения статических полей.

(1) Определить поле в объекте-прототипе. Если вы хотите изменить его, вы должны изменить его через объект-прототип и.

  function Calendar() {
  }

  Calendar.prototype = {
     constructor: Calendar,
     y: 'y',
  };

  function go()
  {
     var c1 = new Calendar();
     var c2 = new Calendar();

     alert("c1.y=" + c1.y + " c2.y=" + c2.y);

     // now setting y to 'YYYYY';
     Calendar.prototype.y = 'YYYYY';

     // both c1 and c2 'see' the new y value
     alert("c1.y=" + c1.y + " c2.y=" + c2.y);  
  }

Опасность этого заключается в том, что вы можете случайно попытаться установить поле y с помощью одного из экземпляров, например: c1.y = 5555, и в этом случае присваивание будет выполняться для объекта c1, но не для объекта c2 .

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

(2) Используйте трюк инкапсуляции Javascript, чтобы убедиться, что поле прототипа доступно только с помощью методов получения и установки.

  function Calendar() {
  }

  function initCalendarPrototype()
  {
     var y = 'y';
     Calendar.prototype = {
         constructor: Calendar,             
         getY: function() { return y; },             
         setY: function(arg) { y = arg; },                    
     };
  }

  function go()
  {
     initCalendarPrototype();

     alert("c1.getY()=" + c1.getY() + " c2.getY()=" + c2.getY());

     // now setting y to 'YYYYY' via setY()
     // Can be invoked on either c1, c2 or Calendar.prototype
     c1.setY('YYYYY') 

     // both c1 and c2 'see' the new y value
     alert("c1.getY()=" + c1.getY() + " c2.getY()=" + c2.getY());
  }
2 голосов
/ 18 декабря 2009

Да, это возможно. В юи они используют

YAHOO.lang.augementObject(Calendar,{/* Properties go here*/});

Но для упрощения, если вы не используете YUI, вы можете сделать это

Calendar.MyStaticVar = {/* Any variables you want*/}

Это позволит вам определить статическую переменную с именем MyStaticVar, в нашем примере это объект, но это может быть строка, число, что вы хотите. Затем, чтобы использовать его, все, что вам нужно сделать, это пойти

Calendar.MyStaticVar

Объект Augment в YUI довольно хорош, потому что вы можете сказать

YAHOO.lang.augementObject(Calendar,{
   StaticVar1:'somevalue',
   StaticVar2:{/*Object value*/},
   StaticVar3:393,
   SomeStaticFunction:function() {}
});

В отличие от

Calendar.StaticVar1 = 'somevalue';
Calendar.StaticVar2 = {/*Object value*/};
Calendar.StaticVar3 = 393;
Calendar.SomeStaticFunction = function() {};
0 голосов
/ 18 декабря 2009

ну, я думаю, статические свойства не для вас Учтите это:

function MyClass(specialProp) {
    if (specialProp) {
        this.prop = specialProp;
    }
}
MyClass.prototype = {"prop":"defaultValue"};
var foo = new MyClass("changed"), bar = new MyClass();
alert(bar.prop);  //got the property from the prototype chain
alert(foo.prop);  //special property of the instance
...