5

I have a bunch of JSON string returned from an ajax call in a specific format and when starting to convert them all into my own Javascript object, I start to wonder if there is any easier way since we're talking Javascript here.

I'll have var manyOfThem = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ]; And I'd like to easily associate each of these objects with my functions so that I can do things like:

myClass.prototype.doSomething = function() {
  // do something to this.name
};

$.each(manyOfThem, function(index, item) {
  item.doSomething();
});

I guess my concern is, I would not want to (because its repetitive) do this:

var myClass = function(item) {
  this.name = item.name;
  // do the same for the rest of item's potentially 20 properties
};

var oneOfThem = new myClass(manyOfThem[0]); // I think this is redundant....
oneOfThem.doSomething();

Anyhow, if there is also (security?) reasons why I'd just have to suck it up and do them all manually please share as well, thanks!

3
  • I think it depends on what you want to in doSomething. Can you share what your plan is? Like why couldn't you just make a function called doSomething and pass item to it? Commented Apr 4, 2013 at 2:34
  • You could always have myClass accept an array (manyOfThem in this case). Then, when you want to manipulate one of its items (calling some doSomething function), you could do myClass.doSomething(3) meaning the 3rd index. Then internally, it would just operate on the 3rd item in the array (without exposing the array). Commented Apr 4, 2013 at 2:38
  • @ian Well, it really could be anything, and if doSomething was a function outside anything it would be 1. in the global namespace, 2. counter-object-oriented design Commented Apr 4, 2013 at 3:02

3 Answers 3

3

You mean, something like (see jsfiddle) :

var MyClass = function() {};
MyClass.prototype = {
    doSomething: function() {
        alert(this.name);
    }
};

Then

var manyObj = $.map(manyOfThem, function(obj) {
   return $.extend( new MyClass(), obj );
});

So you can call :

manyObj[0].doSomething();  // alert("a")

However, this approach will not preserve a direct copy with the manyOfThem object. (In the example above, changing manyOfThem[0].name = "foo"; will not affect manyObj[0] and a call to manyObj[0].doSomething(); will still alert "a". To preserve a direct reference to your object, do this :

var manyObj = $.map(manyOfThem, function(obj) {
    function F() {};
    F.constructor = MyClass;
    F.prototype = obj;
    $.extend(F.prototype, new MyClass());
    return new F();
});


manyObj[0].doSomething();  // alert("a")

manyOfThem[0].name = "foo";  // modify the referenced object

manyObj[0].doSomething();  // alert("foo") ..also modifies the behaviour of the instance
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, thanks a lot, I think the extend function is the key I am looking for. But for preserving a direct reference to my object, can I confirm with you that the prototype will also contain instance variables such as this.name and can be copied over into F.prototype altogether?
Yes, any function or property that is defined will be copied unto the object. For instance, cloning an object is done using : var clone = $.extend({}, sourceObj);. In this case, F.prototype act as a anonymous class level function constructor to create new prototypes using your manyOfThem objects as templates, then extending them with new instances of MyClass (so they each have individual scopes).
I'll have to be honest and say I still don't quite get the concept of object instance properties being copied into a prototype but guess whatever the semantics do, that is what it does. Thanks a lot for your answer!
2

One solution without using a class is

var manyOfThem = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ];

function doSomething(){
    console.log(this.name)
}

$.each(manyOfThem, function(index, item) {
  doSomething.call(item);
});

Demo: Fiddle

If you want to create an instance of type MyClas then

var manyOfThem = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ];

function MyClass(item){
    $.extend(this, item);
}

MyClass.prototype.doSomething = function(){
    console.log(this.name)
}

$.each(manyOfThem, function(index, item) {
    var obj = new MyClass(item);
    obj.doSomething()
});

Demo: Fiddle

Comments

0

You can do

var myClass = function(item){  
    for( i in item){  
        if (item.hasOwnProperty(i)){
            this[i] = item[i];
        }
    }
};

This should reduce the repetitive assignments in myClass constructor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.