Короткий ответ, как сказал Йоханнес, почти всегда №2. Оба будут существовать в памяти только в одном месте, но методы экземпляра имеют контекст (который по сути является дополнительным скрытым аргументом), который дает им доступ к экземпляру.
Но: в некоторых языках / средах функция, которая выглядит (для наивного чтения исходного кода), выглядит как одна функция несколько раз. Хороший пример этого - JavaScript: объект функции закрывается за областью, в которой он определен, поэтому, если имеется несколько областей (например, функция, вызываемая более одного раза), в результате получается несколько различных объектов функции. (Интерпретаторы / JIT-ы могут оптимизировать, дублируется ли код , но концептуально это так, и ссылки на функции отличаются.)
Вот пример в JavaScript:
function foo() {
alert("hi there");
}
function buildBar(x) {
function bar() {
alert(x);
}
return bar;
}
var f1, f2;
f1 = foo;
f2 = foo;
f1();
// alerts "hi there"
f2();
// alerts "hi there"
alert("f1 === f2 ? " + (f1 === f2));
// alerts "true", there is only one `foo`
var b1, b2;
b1 = buildBar("one");
b2 = buildBar("two");
b1();
// alerts "one"
b2();
// alerts "two"
alert("b1 === b2 ? " + (b1 === b2));
// alerts "false", there are two `bar`s
Это становится уместным в некоторых реализациях «частных» данных экземпляра в JavaScript, где люди определяют методы экземпляра в конструкторе (подобно тому, как buildBar
определяет bar
), поэтому они имеют доступ к закрытым переменным, объявленным в конструкторе. Это дает желаемый эффект (частные данные экземпляра), но влияет несколько экземпляров функции - по одному для каждого экземпляра объекта.