JimJim2000 JimJim2000 - 2 months ago 14
JSON Question

JS: json, dynamic method creature and closure

Sorry for not very clear title,but I don't know where the problem is.

So, I need to write a function which creates js objects from json and for fields which begins with underscore it must create setters and getters.

This is test json:

{
"_language":null,
"_country":null
}


This is the function I wrote

function jsonToObject(json){
return JSON.parse(json,function(key,value){
if (value && typeof value === 'object') {
return (function(value){
var replacement = {};
for (var k in value) {
if (Object.hasOwnProperty.call(value, k)) {
//if this is private field
if (k.lastIndexOf("_", 0) === 0){
replacement[k]=value[k];
var name=k.substring(1);
var getName="get"+name.charAt(0).toUpperCase() + name.slice(1);
replacement.constructor.prototype[getName]=function(){
return this[k];
};
var setName="set"+name.charAt(0).toUpperCase() + name.slice(1);
replacement.constructor.prototype[setName]=function(newValue){
this[k]=newValue;
};
//if this is public field
}else{
replacement[k]=value[k];
}
}
}
return replacement;
}(value));
}
return value;
});
}


This is how I test it:

var test1=jsonToObject(data);
test1.setLanguage("11");
console.log("Point A:"+test1.getLanguage());//ouput 11
var test2=jsonToObject(data);
test2.setLanguage("22");
console.log("Point B:"+test2.getLanguage())//output 22
console.log("Point C:"+test1.getLanguage());//output function (a){this[c]=a}
console.log("Point D:"+test2.getLanguage())//output 22


The problem is at point C - the output must be 11. However its output is function... (this code is after optimization, that's why it looks obfucated). Where is my mistake?

Answer

setter and getter duplicate defined

function jsonToObject(json) {
    return JSON.parse(json, function (key, value) {
        if (value && typeof value === 'object') {
            return (function (value) {
                var replacement = {};
                for (var k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        //if this is private field 
                        if (k.lastIndexOf("_", 0) === 0) {
                            replacement[k] = value[k];
                            var name = k.substring(1);
                            var getName = "get" + name.charAt(0).toUpperCase() + name.slice(1);
                            //
                            // check defined
                            //
                            console.log(replacement.constructor.prototype[getName]);
                            //
                            // if defined function, prevent override
                            //
                            if (!/function/.test(typeof replacement.constructor.prototype[getName])) {
                                replacement.constructor.prototype[getName] = function () {
                                    return this[k];
                                };
                            }
                            var setName = "set" + name.charAt(0).toUpperCase() + name.slice(1);
                            // check defined
                            console.log(replacement.constructor.prototype[setName]);
                            // if defined function, prevent override
                            if (!/function/.test(typeof replacement.constructor.prototype[setName])) {
                                replacement.constructor.prototype[setName] = function (newValue) {
                                    this[k] = newValue;
                                };
                            }
                            //if this is public field
                        } else {
                            replacement[k] = value[k];
                        }
                    }
                }
                return replacement;
            }(value));
        }
        return value;
    });
}