Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.07.2012, 19:10
Аспирант
Отправить личное сообщение для bFree Посмотреть профиль Найти все сообщения от bFree
 
Регистрация: 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(...);


Почему так? Имхо, читабельность ниже.
Ответить с цитированием
  #2 (permalink)  
Старый 25.07.2012, 19:14
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от bFree
В чем ужас подобного подхода?
в том что в первый вариант нельзя будет расширить, то-есть унаследовать другим классом, так как все методы будут спрятаны в конструкторе, и получить их через прототип будет не возможно. Второй же вариант дает такую возможность.
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #3 (permalink)  
Старый 25.07.2012, 19:18
Аспирант
Отправить личное сообщение для bFree Посмотреть профиль Найти все сообщения от bFree
 
Регистрация: 19.08.2008
Сообщений: 42

devote,
о, спасибо. Честно говоря я все еще немного запутываюсь в этих прототипах.
Я так понимаю, что foo.prototype - это базовый объект Function? То есть мы добавляем методы к Function() ?

И насчет антипаттерна self = this можете что-либо сказать?
Ответить с цитированием
  #4 (permalink)  
Старый 25.07.2012, 19:19
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Цитата:
var self = this; // Еще один вопрос: это антипаттерн?
Так обычно делают для того, чтобы можно было использовать новосозданный объект внутри функций, определённых внутри конструктора. Если у вас нет таких функций, то и нет смысла так делать, можно внутри конструктора использовать this.

Последний раз редактировалось oneguy, 25.07.2012 в 19:27.
Ответить с цитированием
  #5 (permalink)  
Старый 25.07.2012, 19:22
Аспирант
Отправить личное сообщение для bFree Посмотреть профиль Найти все сообщения от bFree
 
Регистрация: 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(); 
    });
}
Ответить с цитированием
  #6 (permalink)  
Старый 25.07.2012, 19:23
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Сообщение от bFree
Я так понимаю, что foo.prototype - это базовый объект Function? То есть мы добавляем методы к Function() ?
Нет, каждый раз при создании функции для неё создаётся ещё объект - прямой наследник Object.prototype, и для функции устанавливается свойство prototype на него. Это свойство функции prototype можно изменять, установить на другой объект.
Ответить с цитированием
  #7 (permalink)  
Старый 25.07.2012, 19:30
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 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.
Ответить с цитированием
  #8 (permalink)  
Старый 25.07.2012, 20:00
Аспирант
Отправить личное сообщение для bFree Посмотреть профиль Найти все сообщения от bFree
 
Регистрация: 19.08.2008
Сообщений: 42

oneguy,
Жаль, что так громоздко получается =(
Постоянные bind или self = this в каждом методе почти. Да и читабельность ухудшится, если где-то this в методах, где-то self..

Других способо конструировать объекты нет?
Ответить с цитированием
  #9 (permalink)  
Старый 26.07.2012, 22:57
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Сообщение от bFree Посмотреть сообщение
oneguy,
Жаль, что так громоздко получается =(
Постоянные bind или self = this в каждом методе почти. Да и читабельность ухудшится, если где-то this в методах, где-то self..

Других способо конструировать объекты нет?
Вообще-то есть, это очень размытый вопрос, но в данном случае я не вижу лучшего решения проблемы, чем через bind или var self = this.
Ответить с цитированием
  #10 (permalink)  
Старый 26.07.2012, 23:05
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 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));
};
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Скрипт вычисления координат объекта banderasantonio197555 Events/DOM/Window 4 16.08.2011 17:37
прямая от первого объекта до второго ntro123 Events/DOM/Window 5 09.05.2011 08:41
импорт объекта в текущий скоп LedVisel Общие вопросы Javascript 4 06.06.2010 00:31
Как по событию вызвать метод определенного экземпляра объекта jvs jQuery 3 24.12.2009 16:04
Можно ли получить имя экземпляра объекта внутри самого объекта? Ichigeki Общие вопросы Javascript 9 14.11.2008 19:00