Front-end-Job-Interview-Questions
Ответы на вопросы на должность Frontend разработчика.
Project maintained by FedorovAlexander Hosted on GitHub Pages — Theme by mattgraham
В чём разница между «атрибутом» (attribute) и «свойством« (property)?
Атрибуты определены в разметке HTML, а свойства определены в DOM. Большинство стандартных HTML-атрибутов становятся свойствами соответствующих объектов. Но они не идентичны.
Атрибуты
- Всегда являются строками.
- Их имя нечувствительно к регистру.
- Видны в innerHTML.
Свойства
- Могут иметь любое значение.
- Названия свойств чувствительны к регистру.
- Работают за счёт того, что DOM-узлы являются объектами JS.
В чем разница между атрибутом attribute и свойством property
По умолчанию атрибуты в классах являются общедоступными, а это значит, что из любого места программы мы можем получить атрибут объекта и изменить его. Например:
class Person: def __init__(self, name): self.name = name # устанавливаем имя self.age = 1 # устанавливаем возраст def display_info(self): print(f"Имя: \tВозраст: ") tom = Person("Tom") tom.name = "Человек-паук" # изменяем атрибут name tom.age = -129 # изменяем атрибут age tom.display_info() # Имя: Человек-паук Возраст: -129
Но в данном случае мы можем, к примеру, присвоить возрасту или имени человека некорректное значение, например, указать отрицательный возраст. Подобное поведение нежелательно, поэтому встает вопрос о контроле за доступом к атрибутам объекта.
С данной проблемой тесно связано понятие инкапсуляции. Инкапсуляция является фундаментальной концепцией объектно-ориентированного программирования. Она предотвращает прямой доступ к атрибутам объект из вызывающего кода.
Касательно инкапсуляции непосредственно в языке программирования Python скрыть атрибуты класса можно сделав их приватными или закрытыми и ограничив доступ к ним через специальные методы, которые еще называются свойствами .
Изменим выше определенный класс, определив в нем свойства:
class Person: def __init__(self, name): self.__name = name # устанавливаем имя self.__age = 1 # устанавливаем возраст def set_age(self, age): if 1 < age < 110: self.__age = age else: print("Недопустимый возраст") def get_age(self): return self.__age def get_name(self): return self.__name def display_info(self): print(f"Имя: \tВозраст: ") tom = Person("Tom") tom.display_info() # Имя: Tom Возраст: 1 tom.set_age(-3486) # Недопустимый возраст tom.set_age(25) tom.display_info() # Имя: Tom Возраст: 25
Для создания приватного атрибута в начале его наименования ставится двойной прочерк: self.__name . К такому атрибуту мы сможем обратиться только из того же класса. Но не сможем обратиться вне этого класса. Например, присвоение значения этому атрибуту ничего не даст:
tom.__age = 43
Потому что в данном случае просто определяется динамически новый атрибут __age, но это он не имеет ничего общего с атрибутом self.__age .
А попытка получить его значение приведет к ошибке выполнения (если ранее не была определена переменная __age):
print(tom.__age)
Однако все же нам может потребоваться устанавливать возраст пользователя из вне. Для этого создаются свойства. Используя одно свойство, мы можем получить значение атрибута:
def get_age(self): return self.__age
Данный метод еще часто называют геттер или аксессор.
Для изменения возраста определено другое свойство:
def set_age(self, age): if 1 < age < 110: self.__age = age else: print("Недопустимый возраст")
Данный метод еще называют сеттер или мьютейтор (mutator). Здесь мы уже можем решить в зависимости от условий, надо ли переустанавливать возраст.
Необязательно создавать для каждого приватного атрибута подобную пару свойств. Так, в примере выше имя человека мы можем установить только из конструктора. А для получение определен метод get_name.
Аннотации свойств
Выше мы рассмотрели, как создавать свойства. Но Python имеет также еще один - более элегантный способ определения свойств. Этот способ предполагает использование аннотаций, которые предваряются символом @.
Для создания свойства-геттера над свойством ставится аннотация @property .
Для создания свойства-сеттера над свойством устанавливается аннотация имя_свойства_геттера.setter .
Перепишем класс Person с использованием аннотаций:
class Person: def __init__(self, name): self.__name = name # устанавливаем имя self.__age = 1 # устанавливаем возраст @property def age(self): return self.__age @age.setter def age(self, age): if 1 < age < 110: self.__age = age else: print("Недопустимый возраст") @property def name(self): return self.__name def display_info(self): print(f"Имя: \tВозраст: ") tom = Person("Tom") tom.display_info() # Имя: Tom Возраст: 1 tom.age = -3486 # Недопустимый возраст print(tom.age) # 1 tom.age = 36 tom.display_info() # Имя: Tom Возраст: 36
Во-первых, стоит обратить внимание, что свойство-сеттер определяется после свойства-геттера.
Во-вторых, и сеттер, и геттер называются одинаково - age. И поскольку геттер называется age, то над сеттером устанавливается аннотация @age.setter .
После этого, что к геттеру, что к сеттеру, мы обращаемся через выражение tom.age .
Атрибуты и DOM-свойства
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-attributes-and-properties.
При чтении HTML браузер генерирует DOM-модель. При этом большинство стандартных HTML-атрибутов становятся свойствами соответствующих объектов.
Например, если тег выглядит как , то у объекта будет свойство body.id = "page" .
Но это преобразование – не один-в-один. Бывают ситуации, когда атрибут имеет одно значение, а свойство – другое. Бывает и так, что атрибут есть, а свойства с таким названием не создаётся.
Если коротко – HTML-атрибуты и DOM-свойства обычно, но не всегда соответствуют друг другу, нужно понимать, что такое свойство и что такое атрибут, чтобы работать с ними правильно.
Свои DOM-свойства
Ранее мы видели некоторые встроенные свойства DOM-узлов. Но, технически, никто нас ими не ограничивает.
Узел DOM – это объект, поэтому, как и любой объект в JavaScript, он может содержать пользовательские свойства и методы.
Например, создадим в document.body новое свойство и запишем в него объект:
document.body.myData = < name: 'Пётр', familyName: 'Петрович' >; alert( document.body.myData.name ); // Пётр
В чем разница между prop и attr?

Собственно вот и вся разница: первый метод читает/устанавливает значение атрибута элемента (Мержевич по теме), а второй - свойство объекта представляющего элемент. Если вкратце, то разница в том, что они из разной среды: атрибут это термин HTML - вы устанавливаете его в разметке и значение атрибута как-то обрабатывается, влияя на какие-то свойства элемента. А свойства это значения относящиеся непосредственно к DOM объекту элемента.
Например, class, один из самых привычных атрибутов для тега, в элементе представлен свойством className. Если у тега нет атрибута class, то у самого элемента есть свойство className, которое содержит пустую строку. Ну и соотвественно задать класс элементу можно либо изменив атрибут class с помощью attr, либо изменив свойство className с помощью prop.