Прежде всего, вам не нужно писать модули, используя прототип. Подумайте, как если вы пишете что-то вроде класса, вы должны использовать прототипы. А также важно определить, где ваши методы. Определение методов объекта-прототипа и определение их в функции-конструкторе - это совершенно разные вещи!
Давайте посмотрим определение класса образца с помощью методов, определенных в конструкторе:
var Dog = (function() {
var Dog = function (age, name) {
var that = this;
this.age = age;
this.name = name;
this.sayHi = function() {
console.log('Warf! Im ' + that.name); // meaning of "this" changed!!!
};
this.anotherMethod = function() {};
};
return Dog;
}());
var puppy = new Dog(1, 'puppy'); // sayHi and anotherMethod created
var sirius = new Dog(1, 'sirius'); // sayHi and anotherMethod recreated
sirius.sayHi = function() { console.log('Yohalolop!'); };
puppy.sayHi(); // -> 'Warf! Im puppy'
sirius.sayHi(); // -> 'Yohalolop!'
Так что есть некоторые проблемы с приведенного выше примера, во-первых методы определяются как любые другие переменные экземпляра. Фактически, вы определяете их как переменную экземпляра, и это означает, что эти функции воссозданы для каждого создаваемого объекта объекта. Я думаю, вы упомянули, что вы не можете использовать ключевое слово в своих определениях методов. Это ошибка склонна, и есть возможность забыть об этом и использовать это ключевое слово ошибкой. Иногда вы можете использовать методы как переменные экземпляра, так же как переменные обратные вызовы.
Давайте посмотрим определение класса образца с объекта-прототипа:
var Dog = (function() {
var Dog = function (age, name) {
this.age = age;
this.name = name;
};
// sayHi method defined only once in prototype
Dog.prototype.sayHi = function() {
console.log('Warf! Im ' + this.name; // we can use this keyword
};
// anotherMethod defined only once in protoype
Dog.prototype.anotherMethod() {
};
return Dog;
}());
var puppy = new Dog(1, 'puppy');
var sirius = new Dog(1, 'sirius'); // sirius and puppy sharing same prototype object
puppy.sayHi(); // -> 'Warf! Im puppy'
sirius.sayHi(); // -> 'Warf! Im sirius'
// remember puppy and sirius sharing same prototype object
Dog.prototype.sayHi = function() {
console.log('Yohalolop');
};
puppy.sayHi(); // -> 'Yohalolop'
sirius.sayHi(); // -> 'Yohalolop'
В ответ на ваш вопрос о частных функциях, это сложнее. Да, вы можете использовать частные функции, даже если вы определяете свои методы на прототипе, но есть некоторые проблемы с тестированием. Их использование зависит от вас. Я предпочитаю не использовать. Позвольте мне привести несколько примеров.
var Calculator = (function() {
var Calculator = function() {
this.importantNumber = 2;
};
// There is unfortunately no native implementation
// for private methods but you can mimic them with
// unaccessible functions and binding.
var someExtremeComputations = function() {
return 40 + this.importantNumber; // this keyword points to instance because of binding
};
Calculator.prototype.getMeaningOfLife = function() {
var result = someExtremeComputations.call(this); // we bind function to instance
return result;
};
return Calculator;
}());
Это один из примеров того, как вы можете определить частные методы в javascript.Проблема с частными функциями, они не могут быть протестированы. Невозможно протестировать метод someExtremeComputations.
Некоторые люди (включая меня) используют префиксное соглашение об именовании underscore для частных методов. Таким образом, они на самом деле являются общедоступными методами, но если кто-то их назвал или переопределив, они были предупреждены префиксом подчеркивания. В конце концов, мы можем тестировать частные методы, поскольку они общедоступны.
var Calculator = (function() {
var Calculator = function() {
this.importantNumber = 2;
};
// private method's name prefixed by an underscore to warn
// other developers to be careful about that or not to use.
Calculator.prototype._someExtremeComputations = function() {
return 40 + this.importantNumber;
};
Calculator.prototype.getMeaningOfLife = function() {
var result = this.someExtremeComputations(); // no need to bind
return result;
};
return Calculator;
}());
См http://stackoverflow.com/questions/4736910/javascript-when-to-use-prototypes – mccainz
Все свойства объекта JS являются общедоступными, есть на самом деле не разница. Вы помещаете эти свойства в прототип, который * все экземпляры разделяют *. – Bergi