Когда имеет смысл использовать функции-прототипы вместо замыканий?
Ну, это самый легкий способ, скажем, у вас есть метод в prototype
определенного конструктора, и вы создаете 1000 экземпляров объектов, все эти объекты будут иметь ваш метод в своей цепочке прототипов, и все они будут ссылаться только на один функциональный объект .
Если вы инициализируете этот метод внутри конструктора, например, (this.method = function () {};
), все ваши 1000 экземпляров объекта будут иметь функциональный объект как собственное свойство.
Если мне по какой-то причине нужно использовать функцию-прототип, то нормально ли это определять ее внутри класса, как в моем примере, или она должна быть определена снаружи?
Определение членов прототипа конструктора внутри себя, не имеет особого смысла, я объясню вам больше об этом и почему ваш код не работает.
Я хотел бы понять, почему значение privateVar каждого экземпляра недоступно для функции-прототипа, только значение первого экземпляра.
Давайте посмотрим ваш код:
var Container = function(param) {
this.member = param;
var privateVar = param;
if (!Container.prototype.stamp) { // <-- executed on the first call only
Container.prototype.stamp = function(string) {
return privateVar + this.member + string;
}
}
}
Ключевым моментом в поведении вашего кода является то, что функция Container.prototype.stamp
создается при первом вызове метода.
В тот момент, когда вы создаете объект функции, он сохраняет текущую область видимости во внутреннем свойстве с именем [[Scope]]
.
Эта область позже расширяется при вызове функции с помощью идентификаторов (переменных), объявленных в ней с помощью var
или FunctionDeclaration.
Список [[Scope]]
свойств образует цепочку области действия , и когда вы обращаетесь к идентификатору (например, к переменной privateVar
), эти объекты проверяются.
И так как ваша функция была создана при первом вызове метода (new Container('A')
), privateVar
привязана к Scope этого первого вызова функции, и она останется привязанной к ней независимо от того, как вы вызываете метод.
Посмотрите на этот ответ , первая часть посвящена выражению with
, но во второй части я расскажу о том, как работает цепочка областей действия для функций.