В основе объектно-ориентированного программированиия (ООП) лежат две сущности: класс и объект.
Основные парадигмы ООП:
В JavaScript все переменные и функции, имеющие глобальную область видимости, являются свойствами специального объекта, который называется глобальный объект. В браузере этот объект доступен как window.
Выполнение программы происходит в два этапа:
Все переменные внутри функции являются свойствами специального внутреннего объекта LexicalEnvironment, который создаётся при её запуске.
Функция имеет доступ не только к локальным, но и к глобальным переменных. При доступе к переменной она сначала ищется в LexicalEnvironment функции, а затем — в LexicalEnvironment того объекта, в котором была вызвана функция, пока переменная не будет обнаружена. Внешние по отношению к данной функции переменные хранятся в скрытом объекте [[Scope]], который является ссылкой на LexicalEnvironment, в котором функция была создана.
Внутри функций можно создавать другие, вспомогательные функции. Такие функции так же, как и обычные переменные, будут иметь локальную область видимости для "функции-родителя". У таких функций будет свой [[Scope]], состоящий из LexicalEnvironment "функции-родителя".
Т.к. функция в JavaScript является объектом, то ей, как и любому объекту, можно добавлять свойства и методы. Такие свойства будут доступны везде, где будет доступна сама функция.
Как и к другим типам данных к объектам может применяться одно из трёх преобразований типов: логическое, численное, строковое.
Любой объект, даже пустой, при логическом преобразовании всегда возвращает true.
При строковом преоборазовании выведется результат выполнения метода toString, если такой есть в объекте, а иначе - просто строка [object Object]. Созданный программистом метод toString может возвращать любое примитивное значение, причем не только строку, так что такое преобразование называется именно строковым преобразованием, а не преобразованием к строке.
Для численного преобразования объекта используется метод valueOf, а если такого метода нет — то метод toString. Метод valueOf также может возвращать любой примитив, необязательно число. У большинства встроенных объектов метод valueOf отсутствует, поэтому для численного преобразования применяется метод toString.
Ключевое слово this указывает на объект, который вызвал данную функцию. Если метод объекта использует this, то в таком случае this ссылаеся на сам этот объект.
Конструктором является любая функция, вызванная через new
function Car(name) {
this.name = name;
this.wheels = 4;
this.addWheel = function(wheelNum) {
this.wheels += wheelNum;
};
}
var car = new Car("Mersedes");
По окончании своей работы функция-конструктор возвращает ссылку на вновь созданный объект. Но это поведение может меняться, если добавить return в функцию.
Если return вернет примитив, то он не будет учитываться, т.е. функция-конструктор отработает так, как если бы return не было. Если return вернет объект, то функция вернет этот.
Если в конструктор не нужно передавать никакие параметры, то его можно вызывать без скобок.
Помимо обычного создания свойств объекта есть ещё "продвинутое" — через метод Object.defineProperty. Метод принимает три параметра, третьим является дескриптор — объект-конфигурация вновь созданного свойства.
var car = {};
car.color = "red"; // обычное добавление свойства
Object.defineProperty(car, "speed", { // добавление свойства с помощью дескриптора
value: 100, // значение свойства
configurable: true, // возможность удалять свойство (только в use strict)
writable: true, // возможность изменять значение свойства (только в use strict)
enumerable: true // "перечисляемость" свойства
});
Object.defineProperty(car, "carInfo", {
get: function() {
return "My speed is " + this.speed;
},
set: function(value) {
this.speed = value;
},
});