В чем различия этих конструкций в JavaScript?

Привет, всем!
Прошу объяснить, пожалуйста
Есть такие конструкции:
function Person (name, age) {
	this.name = name;
	this.age = age;
	this.getName = getName;
}

function getName() {
		return this.name;
};

var Mike = new Person('Mike', 24);
var John = new Person('John', 30);

Mike.getName === John.getName;// true

и вот эта:

function Person (name, age) {
	this.name = name;
	this.age = age;
}

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

var Mike = new Person('Mike', 24);
var John = new Person('John', 30);

Mike.getName === John.getName;// и здесь true


Если объекты ссылаются на одну функцию и дают true при сравнении, то есть ли смысл использовать свойство prototype, есть ли разница в конструкциях?
  • Вопрос задан
  • 2615 просмотров
Решения вопроса 2
In4in
@In4in
°•× JavaScript Developer ^_^ ו°
1) Все должно быть на своем месте, разложено по полочкам, это основа JavaScript кода. Оправдывается это тем, что над кодом могут работать несколько человек и если у каждого будет свой бардак, то в итоге кто-то может сделать вот так:
function getName(){...} //вы объявили функцию
//code
//code
function getName(){..} //Еще какой-то господин объявил функцию
//Что в итоге? -Объявлена будет вторая.

2) Статичные свойства объекта принято выносить в его прототип, так как создавать множество объектов с идентичным методом getName - глупо, только память забивать.

И если и уподобляться первому варианту, то так:

function Person (name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.getName = getName;

function getName() {
    return this.name;
};

var Mike = new Person('Mike', 24);
var John = new Person('John', 30);

Mike.getName === John.getName;// true
Ответ написан
k12th
@k12th
console.log(`You're pulling my leg, right?`);
Краткий ликбез по JS: Как работает прототипное наследование: при обращении к свойству оно ищется сначала в самом объекте, потом, если не найдено, в том объекте, который указан как прототип (скрытое свойство [[Prototype]]) для исходного, потом в прототипе прототипа и так далее, пока прототип не null. Что происходит, когда мы вызываем new SomeFunction(): создается новый объект у которого [[Prototype]] ссылается на SomeFunction.prototype, в контексте этого нового объекта вызывается SomeFunction (как если бы через apply или call), полученный объект возвращается.

1) В первом варианте у вас в конструкторе лишняя операция. А если таких методов 10? А если надо создать 10000 таких объектов?
2) Во первом варианте у вас каждый инстанс будет непосредственно иметь ссылку на getName. Во втором — каждый инстанс будет иметь ссылку на прототип, в котором уже будет ссылка на getName. Значит, первый вариант будет жрать поболе памяти (однако обращение к методу getName будет работать чуточку быстрее).
3) Можно так делать, если очень надо переопределить getName для данного объекта. Но с точки зрения архитектуры — не стоит, лучше создать отдельный класс или фабричную функцию, которая будет возвращать объект с нужным getName. Причина: black magic, который задолбаешься искать по коду.
4) На данный момент времени, можно, наверное, начинать писать на ES2015 с нативными классами, чтобы не придумывать велосипеды с колесами из костылей:)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы