Проблема в том, что присвоение this[ "get" + i ] = function() {} происходит в анонимной функции, которой не присвоен контекст. Значит, контекстом является глобальный объект.
В данном случае геттеры и сеттеры создаются не у создаваемого объекта, а у глобального объекта (в браузере это window), поэтому вы вообще можете запустить функцию getname(). Её просто нет у объекта, но она есть в глобальном пространстве.
Чтобы исправить, нужно в конструкторе в начале сделать ссылку на this и присваивать геттеры/сеттеры объекту через эту ссылку, а не через ключевое слово this.
function User( properties ) {
var user = this;
for ( var i in properties ) {
(function(){
user[ "get" + i ] = function() {
return properties[i];
};
user[ "set" + i ] = function(val) {
properties[i] = val;
};
})();
}
}
Верно отметил
@Fesor в соседнем ответе, лучше не плодить переменные, если можно указать контекст вызова явно:
function User( properties ) {
for ( var i in properties ) {
(function(){
this[ "get" + i ] = function() {
return properties[i];
};
this[ "set" + i ] = function(val) {
properties[i] = val;
};
}).call(this);
}
}