Как я могу эмулировать "классы" в JavaScript? (с или без сторонней библиотеки)
Как я могу эмулировать классы (и пространства имен) в JavaScript?
Мне нужно создать библиотеку JavaScript и иметь ограниченный опыт работы с языком. Я всегда думал, что у него есть родная поддержка классов, но он менее связан с Java, чем я предполагал. Кажется, что все в JavaScript на самом деле является функцией.
То, что я обнаружил до сих пор, имеет большой смысл, поскольку он является динамически слабо типизированным языком, но это делает его немного отходом для людей, которые привыкли иметь строго типизированный язык и использовать компилятор для определения наши ошибки:)
Я в основном работаю на С# и Java и надеялся на что-то синтаксически похожее, чтобы библиотека выглядела знакомой для наших других разработчиков С#, которые должны будут ее поддерживать.
У меня есть следующий вид кода, который работает, но мне было интересно, что будет делать другой разработчик. Каковы альтернативы? Есть ли способ, который лучше? Есть ли способ, который более читабельен?
Я понимаю, что то, что я хочу, похоже на С# или Java, когда я должен просто согласиться с тем, что этот - это JavaScript, но моя цель - попытаться ослабить кривую обучения для других разработчиков что делает его более знакомым и интуитивным для них.
//Perform the namespace setup (this will actually be done with checking
//in real life so we don't overwrite definitions, but this is kept short
//for the code sample).
var DoctaJonez = new function();
DoctaJonez.Namespace1 = new function();
/**
* Class description.
*/
DoctaJonez.Namespace1.SomeClass = function()
{
/**
* Public functions listed at the top to act like a "header".
*/
this.publicFunction = privateFunction;
/**
* Private variables next.
*/
var privateVariable;
/**
* Finally private functions.
*/
function privateFunction()
{
}
}
//Create an instance of the class
var myClass = new DoctaJonez.SomeClass();
//Do some stuff with the instance
myClass.publicFunction();
Ответы
Ответ 2
Для общего понимания ООП в JavaScript вы не можете сделать лучше, чем читать Дуглас Крокфорд:
- Классическое наследование в JavaScript
- Прототипное наследование в JavaScript
- Частные члены в JavaScript
Для поклонников Dojo (и для общих методов) Нил Робертс имеет хорошие статьи:
Обычная ваниль dojo.declare(), вероятно, является самой передовой базой ООП в основных библиотеках. Я предвзятый, но не верю мне на слово. Вот примеры того, как его использовать.
Обычный ванильный объект:
// Let define a super simple class (doesn't inherit anything).
dojo.declare("Person", null, {
// Class-level property
answer: 42,
// Class-level object property
name: {first: "Ford", last: "Prefect"},
// The constructor, duh!
constructor: function(age){
this.age = age; // instance-level property
},
// A method
saySomething: function(verb){
console.log("I " + verb + " " +
this.name.first + " " + this.name.last + "!" +
" -- " + this.answer);
},
// Another method
passportControl: function(){
console.log("I am " + this.age);
}
});
Пример использования:
// A fan of Ford Perfect
var fan = new Person(18);
fan.saySomething("love"); // I love Ford Perfect! -- 42
fan.passportControl(); // I am 18
Одиночное наследование легко:
// Let create a derived class inheriting Person
dojo.declare("SuperAgent", Person, {
// Redefine class-level property
answer: "shaken, not stirred",
// Redefine class-level object property
name: {first: "James", last: "Bond"},
// The constructor
constructor: function(age, drink){
// We don't need to call the super class because
// it would be done automatically for us passing
// all arguments to it.
// At this point "age" is already assigned.
this.drink = drink; // Instance-level property
},
// Let redefine the method
saySomething: function(verb){
// Let call the super class first
this.inherited(arguments);
// Pay attention: no need for extra parameters, or any extra code,
// we don't even name the class we call --- it is all automatic.
// We can call it any time in the body of redefined method
console.log("Yeah, baby!");
},
shoot: function(){ console.log("BAM!!!"); }
});
Пример использования:
// Let create a James Bond-wannabe
var jb007 = new SuperAgent(45, "Martini");
jb007.saySomething("dig"); // I dig James Bond! -- shaken, not stirred
// Yeah, baby!
jb007.passportControl(); // I am 45
jb007.shoot(); // BAM!!!
// Constructors were called in this order: Person, SuperAgent
// saySomething() came from SuperAgent, which called Person
// passportControl() came from Person
// shoot() came from SuperAgent.
Примеси:
// Let define one more super simple class
dojo.define("SharpShooter", null, {
// For simplicity no constructor
// One method to clash with SuperAgent
shoot: function(){
console.log("It jammed! Shoot!");
}
});
Множественное наследование на основе Mixin:
// Multiple inheritance
dojo.declare("FakeAgent", ["SuperAgent", "SharpShooter"], {
// Let do it with no constructor
// Redefine the method
saySomething: function(verb){
// We don't call super here --- a complete redefinition
console.log("What is " + verb "? I want my " + this.drink + "!");
},
});
Пример использования:
// A fake agent coming up
var ap = new FakeAgent(40, "Kool-Aid");
ap.saySomething("hate"); // What is hate? I want my Kool-Aid!
ap.passportControl(); // I am 40
ap.shoot(); // It jammed! Shoot!
// Constructors were called in this order: Person, SuperAgent
// saySomething() came from FakeAgent
// passportControl() came from Person
// shoot() came from SharpShooter.
Как вы можете видеть, dojo.declare()
предоставляет все необходимые вещи с простым в использовании API: прямое однонамерное наследование, множественное наследование на основе mixin, автоматическое объединение конструкторов и супер-методы без излишеств.
Ответ 3
Например, в http://mckoss.com/jscript/object.htm.
Вы найдете множество примеров, когда googling для "JavaScript-объектно-ориентированного". Взглянув на популярные JavaScript-фреймворки, такие как Ext JS, вы получите представление об этих концепциях и о том, как они применяются на практике.
Ответ 4
mepcotterell предоставляет хорошие ссылки, но я хотел бы добавить, что лично я предпочитаю видеть пространства имен как объекты, т.е. DoctaJonez.Namespace1 = {};
.
Ответ 5
Используя MooTools. См. Статью Как написать класс Mootools.
Ответ 6
Если вы (и ваша команда) используется на Java, но вам нужно сделать какой-то JavaScript для веб-сайта, возможно, вам стоит подумать о Google Web Toolkit (GWT). Он позволяет вам кодировать JavaScript с использованием Java, который преобразуется в JavaScript. Однако я не пробовал.
JavaScript на самом деле довольно классный язык. У него есть несколько недостатков (в том числе позволяет вам делать очень глупые вещи), но с небольшим самодисциплином вы можете сделать отличный материал. JavaScript на самом деле объектно-ориентированный, не столько ориентированный на класс, но и вы можете делать многое из того же материала. У вас нет наследства (AFAIK), но он не является строгим (одна из его мощных, но и опасных функций) с набрав, поэтому вы не найдете этого ограничения.
Ответ 7
См. Сеть разработчиков Mozilla (MDC) Class- Основанные на языках прототипов.