25.07.2012, 19:10
|
Аспирант
|
|
Регистрация: 19.08.2008
Сообщений: 42
|
|
Правильное оформление объекта
Встала необходимость освоить JS на хорошем уровне. Возник вопрос.
В чем ключевое отличие между способами создания объектов и их членов/методов?
Также почему я часто вижу какие-то велосипеды для эмуляции приватных свойств, когда они и так есть "из коробки" ?
Вот пример:
// Как начал писать я
function foo(init_params) {
var self = this; // Еще один вопрос: это антипаттерн?
var private_member; // Я вижу приватные свойства так
var init = function(self) {
// конструктор
}
// Публичные методы
self.someMethod = function(params) {
// Метод
}
// --- //
init(self); // вызов конструктора
}
var bar = new foo(params);
bar.someMethod(...);
В чем ужас подобного подхода? Везде, где я смотрю и читаю, я вижу такое:
function foo() {
var privateMember;
this.publicMember = false;
}
foo.prototype.method = function(a) {
// метод
};
var bar = new foo();
b.method(...);
Почему так? Имхо, читабельность ниже.
|
|
25.07.2012, 19:14
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Сообщение от bFree
|
В чем ужас подобного подхода?
|
в том что в первый вариант нельзя будет расширить, то-есть унаследовать другим классом, так как все методы будут спрятаны в конструкторе, и получить их через прототип будет не возможно. Второй же вариант дает такую возможность.
|
|
25.07.2012, 19:18
|
Аспирант
|
|
Регистрация: 19.08.2008
Сообщений: 42
|
|
devote,
о, спасибо. Честно говоря я все еще немного запутываюсь в этих прототипах.
Я так понимаю, что foo.prototype - это базовый объект Function? То есть мы добавляем методы к Function() ?
И насчет антипаттерна self = this можете что-либо сказать?
|
|
25.07.2012, 19:19
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Цитата:
|
var self = this; // Еще один вопрос: это антипаттерн?
|
Так обычно делают для того, чтобы можно было использовать новосозданный объект внутри функций, определённых внутри конструктора. Если у вас нет таких функций, то и нет смысла так делать, можно внутри конструктора использовать this.
Последний раз редактировалось oneguy, 25.07.2012 в 19:27.
|
|
25.07.2012, 19:22
|
Аспирант
|
|
Регистрация: 19.08.2008
Сообщений: 42
|
|
oneguy,
Я пишу var self = this; для того, чтобы можно было вызывать методы этого класса внтури, например, jQuery.each, т.к. там this переопределяется.
self.someMethod = function() {};
self.someEach = function() {
jQuery.each(domObjects, function(i, obj) {
self.someMethod();
});
}
|
|
25.07.2012, 19:23
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от bFree
|
Я так понимаю, что foo.prototype - это базовый объект Function? То есть мы добавляем методы к Function() ?
|
Нет, каждый раз при создании функции для неё создаётся ещё объект - прямой наследник Object.prototype, и для функции устанавливается свойство prototype на него. Это свойство функции prototype можно изменять, установить на другой объект.
|
|
25.07.2012, 19:30
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от bFree
|
Я пишу var self = this; для того, чтобы можно было вызывать методы этого класса внтури, например, jQuery.each, т.к. там this переопределяется.
|
Правильно. я о том же и говорил. У вас есть функция, объявленная внутри конструктора, которая должна использовать объект, созданный конструктором. Однако есть метод someEach задаёт общее поведение всех объектов класса, то его нужно записать в прототип, как показали ранее.
foo.prototype.someEach = function() {
var self=this;
jQuery.each(domObjects, function(i, obj) {
self.someMethod();
});
};
Вместо var self=this; можно использовать ещё другой подход - с помощью метода Function.prototype.bind.
foo.prototype.someEach = function() {
jQuery.each(domObjects, function(i, obj) {
this.someMethod();
}.bind(this));
};
Последний раз редактировалось oneguy, 26.07.2012 в 23:03.
|
|
25.07.2012, 20:00
|
Аспирант
|
|
Регистрация: 19.08.2008
Сообщений: 42
|
|
oneguy,
Жаль, что так громоздко получается =(
Постоянные bind или self = this в каждом методе почти. Да и читабельность ухудшится, если где-то this в методах, где-то self..
Других способо конструировать объекты нет?
|
|
26.07.2012, 22:57
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от bFree
|
oneguy,
Жаль, что так громоздко получается =(
Постоянные bind или self = this в каждом методе почти. Да и читабельность ухудшится, если где-то this в методах, где-то self..
Других способо конструировать объекты нет?
|
Вообще-то есть, это очень размытый вопрос, но в данном случае я не вижу лучшего решения проблемы, чем через bind или var self = this.
|
|
26.07.2012, 23:05
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от oneguy
|
foo.prototype.someEach = function() {
jQuery.each(domObjects, function(i, obj) {
this.someMethod();
}.bind(this));
};
|
Кстати, в этом случае, если в анонимной функции только вызывается один метод, то его необязательно заворачивать в функцию, достаточно только применить bind.
foo.prototype.someEach = function() {
jQuery.each(domObjects, foo.prototype.someMethod.bind(this));
};
|
|
|
|