staffID
@staffID

Как различать методы и свойства в ооп?

Вот напимер класс
var FirstClass = function() {
this.name //как я понял это свойство
};
FirstClass.prototype.dataName = {...}; //это метод
var first_class = new FirstClass();


Когда стоит применять методы, а когда свойства?
  • Вопрос задан
  • 505 просмотров
Решения вопроса 1
@f_ban
Метод - функция, которая представляет собой значение свойства ( es5.javascript.ru/x4.html#x4.3.27 )

Ну а раз уж мы выяснили что это функция, то...
Функция - элемент типа Object, являющийся экземпляром стандартного встроенного конструктора Function, который может быть вызван в качестве подпрограммы. ( es5.javascript.ru/x4.html#x4.3.24 )

... а следовательно...
function isFunction(obj){
  return (typeof(obj)) === "function";
}


Конкретно у вас, this.name - свойство объекта, создаваемого вызовом конструктора класса FirstClass. FirstClass.prototype.dataName - свойство объекта-прототипа класса FirstClass. Являются они методами или нет, можно выяснить вызовом выше описанной функции isFunction.

Дело в том, что в спецификации ECMA Script 5 ( es5.javascript.ru ) нет понятия классов как таковых. Зато есть конструкторы объектов (оператор new) которому можно передать практически любую функцию, которая будет использована как функция конструктора. Функции имеют свойство prototype, которое используется для передачи "родительского" поведения и свойств потомкам. Такое наследование называется прототипным.
При реализации наследования механизм таков. Свойство prototype по сути хранит в себе шаблон объекта, который будет получен при конструировании объекта вызовом оператором new. Есть одно но, свойства объекта из prototype родительского класса записываются не в свойства создаваемого объекта (точнее ссылка целиком на объект, на который ссылается prototype), а в его специальное свойство __proto__ (то есть добавляются в цепочку прототипов).
Посмотри вот такой трюк.

// Объявляем первый класс
Class1 = function(name){this.name = name}
Class1.prototype.family = "Super Class"

// Объявляем второй класс
Class2 = function(name){this.name = name;this.family = "Class";}
// Именно так правильнее указывать родительский класс
Class2.prototype = Object.create(Class1.prototype)

o = new Class2("MyName");

console.log(o.name);
console.log(o.family);

// Объект отказался от своего имени и фамилии
delete o.name;
delete o.family;

// от имени и фамилии можно отказаться
console.log(o.name);
// но не от родовой метки :)
console.log(o.family);


Дело в том, что свойство family было удалено из объекта, но оно есть в объекте, на который ссылается свойство o.__proto__, следуя по цепочке прототипов интерпретатор находит свойство family и возвращает его значение
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Atanvar
@Atanvar
Frontend developer
свойства - какие-то данные класса (имя, возраст, пол и тд)
методы - какие-то действия класса (Сходить, вызвать, погавкать, прыгнуть и тд)
Ответ написан
@dmz9
дело в инкапсуляции.
у объекта могут быть открытые (публичные) и закрытые (приватные) свойства/методы.
в JS это слабее выражено (но это можно имитировать), но в других языках такие модификаторы есть.
разница в том что открытые свойства доступны любому другому объекту/методу, взаимодействующему с изначальным объектом. аналогично и публичные методы нужны для открытого взаимодействия. приватные нужны только для себя, также как и некоторые методы нужны только внутри объекта но не снаружи.
использовать ли для объектов свойства? можно вообще не использовать. вместо этого используй чтения-записи значений. однако это усложняет код.
если пишешь код на публику - тогда делай эти методы.
если пишешь код в своем маааленьком приложении - смысла в этом мало.
пример закрытых и открытых свойств. на самом деле "во внешний мир" отдается другой объект, однако это не значит что он перестал "работать".
var TheConstructor = function(params) {
    var
        happinessCap = 100,
        desireCap = 100,
        ageFactor = (function(age) {
            return 33 / age;
        })(params.age),
        maxAge=45,
        minAge=18,
        woman = {
            _age: params.age,
            _happiness: 42,
            _desire: 0,
            bitchCoeff: params.bitchCoeff
        };
    woman.dance = function() {
        woman._happiness += woman._age / woman.bitchCoeff;
        if (woman._happiness >= happinessCap) {
            woman._happiness = happinessCap;
        }
    }
    woman.drinkAlcohol = function() {
    	if(woman._age<minAge){
    		throw new AgeRestriction(woman._age);
    	}
    	if(woman._age>maxAge){
    		return;
    	}
        woman._desire += woman._age * ageFactor / woman.bitchCoeff;
        if (woman._desire >= desireCap) {
            woman._desire = desireCap;
        }
    }
    woman.isAccessible = function() {
        return (woman._happiness == happinessCap && woman._desire == desireCap);
    }
    return {
        dance: woman.dance,
        drink: woman.drinkAlcohol,
        isAccessible: woman.isAccessible,
        own:function(){
        	return (woman.bitchCoeff<1)?woman:{};
        }
    }
}
function seduce(woman){
	var maxAttempts = 5;
	for(var i = 1;i<=maxAttempts;i++){
		woman.drink();
		woman.dance();
		if(woman.isAccessible()){
			console.log(woman.name + " has been seducted after "+i+" attempts!");
			console.info(woman.own());
			return true;
		}
	}
	console.error(woman.name + " is a frigid bitch!");
	return false;
}
var cheerLeader = new TheConstructor({age:20,bitchCoeff:0.25})
cheerLeader.name = "Masha";
seduce(cheerLeader);
var businessWoman = new TheConstructor({age:33,bitchCoeff:2.5})
businessWoman.name="Olga Victorovna";
seduce(businessWoman);
var schoolTeacher = new TheConstructor({age:27,bitchCoeff:1.1})
schoolTeacher.name="Valentina";
seduce(schoolTeacher);

------------
свойства начинаются с мелкой буквы, являются именами существительными, если больше 1 слова пишется кемел-кейс.
приватные свойства начинаются с подчеркивания (так проще различать). например
если юзаешь джиквери - есть негласное соглашение (а может где то и зафиксировано), что свойство или переменная содержащая джиквери объект начинается с $, например this.$container = $('.container');
-------------
методы - тоже начинаются с мелкой буквы, являются глаголами. если больше 1 слова пишется кемел-кейс, первое слово всеравно глагол, остальные могут быть существительными. например this.getStorageData('orders'), типа, получить данные (заказы) из хранилища.
есть еще методы - конструкторы. это методы объекта которые возвращают не просто результат, а целый новый объект, в который напиханы разные свойства. методы конструктора обычно начинают с БольшойБуквы.
например
this.BuildWidget = function(widgetParams){ var widget={params:widgetParams}; ... ; return widget; }.

-------------
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы