javascript. About objects

При вызове с оператором new функция-конструктор всегда возвращает объект. По умолчанию это объект, на который указывает ссылка this. Если внутри конструктора к нему не добавляются никакие свойства, возвращается "пустой" объект ("пустой", если не считать свойства и методы, унаследованные от прототипа конструктора). Конструкторы неявно возвращают значение this, даже если в них отсутствует инструкция return. Однако сохраняется возможность вернуть любой другой объект по своему усмотрению. Стоит помнить, что если вызвать конструктор без оператора new, ссылка this будет указывать на глобальный объект. В браузерах ссылка this будет указывать на объект window. Если в конструкторе создается какое-либо новое свойство, такое как this.member, то при вызове конструктора без оператора new будет создано новое свойство глобального объекта, к которому можно будет обратиться так: window.member или просто member. Чтобы этого избежать нужно использовать конструктор иначе.

function Person(name) {
    var that = {};
    that.name = name || '';
    return that;
}


Но в этом случае будет утрачена связь с прототипом, поэтому все члены, добавленные к прототипу функции Person, окажутся недоступными для объектов. Чтобы этого избежать, нужно немного видоизменить конструктор:

function Person(name) {

    if (!(this instanceof Person)) {
        return new Person(name);
    }
   
    this.name = name || '';

}

Person.prototype.getName = function () {
    return this.name;
};

var Darvin = Person('Darvin');
console.log(Darvin.getName()); // Darvin

var Einstein = new Person('Einstein');
console.log(Einstein.getName()); // Einstein


Как видно из примера, все работает как положено.
Вообще стоит подметить, при каждом вызове конструктора в памяти создаются новые функции и новые переменные (свойства). Совершенно очевидно, что это неэкономный подход к расходованию памяти, потому что реализация не изменяется от одного экземпляра к другому. Поэтому эффективней добавлять такие методы и свойства к прототипу функции-конструктора.

MyConstructor.prototype.property = true;
 

MyConstructor.prototype.getProperty = function () {
    return this.property;
};


Любой объект имеет свойство constructor, это ссылка на конструктор данного объекта:

var Adam = new Person('Adam');
var Eva = new Person('Eva');
var Cain = new Eva.constructor('Cain'); // здесь мы обращаемся к конструктору Person

Также можно обращаться и к прототипу конструктора:

Cain.constructor.prototype.child = true;

Создание объектов в форме литералов очень удобно, но при этом теряется возможность проверок следующего типа. Выше был создан объект Adam, конструктором которого является Person, значит в коде можно использовать следующую проверку:

Adam instanceof Person // true

Для объектов в форме литералов конструктор является анонимным, то есть так проверить на соответствие типу не удастся. Стоит также подметить. что в случае каскадного наследования объекты также могут подвергаться проверке, например:

var Mammal = function () {
    this.name = 'mammal';
    this.getName = function () {
        return this.name;
    };
};

var Dog = function (name) {
    this.name = name || 'dog';
};

Dog.prototype = new Mammal;

var Bob = new Dog('Bob');

console.log(Bob instanceof Dog); // true
console.log(Bob instanceof Mammal); // true


То есть проверка проходит не только по своему типу. но и по родительскому. На последок небольшая схемка. Всем успехов в Ваших делах.