4

I have the following code:

this.myObject = {
   key1: "val1",
   key2: "val2"
}

this.aMethod = function (newObject) {
    ...

Here I want a new object (probably that inherits from this.myObject) that contains everything in this.myObject plus whatever is in newObject also, fields in newObject should override already existing fields in this.myObject

How do I do this?

This idea is that this.myObject provides some default values - but the user of the method can override these values. I'm open to criticisms of this overall "pattern" as well. Thanks.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
bba
  • 14,621
  • 11
  • 29
  • 26
  • In the future, instead of asking your question in "code comments", ask it in the question text - people can see the question as containing text only and close it as "not a real question". – Oded Nov 11 '10 at 13:14
  • Is this global code or function code? – Šime Vidas Nov 11 '10 at 13:22
  • the code I showed above is itself inside of a prototype method – bba Nov 11 '10 at 13:31
  • @bba I would like to see the whole pattern (the whole prototype method) – Šime Vidas Nov 11 '10 at 13:38
  • That is pretty much the entire code. Just wrap it in something like: SomeObject.prototype.Method = function() { ... }; – bba Nov 11 '10 at 13:40
  • @bba SomeObject is a custom object, or a built-in object? How are you using this prototype method? Are you creating new instances of SomeObject via new SomeObject()? – Šime Vidas Nov 11 '10 at 13:45
  • its a custom object which I use by doing var someObject = new SomeObject(); – bba Nov 11 '10 at 13:46
  • @bba Ok, so you create a new instance ( var obj_1 = new SomeObject(); ) and then you call the prototype method on that instance object ( obj_1.theMethod(); )... That method will then add the myObject object to the instance object (as a property) ( obj_1.myObject )... and it will also add the aMethod fuction ( obj_1.aMethod )... And then you want to call this aMethod method with an object as an argument, and you want that passed in object to inherit from the myObject object that is a property of obj_1, correct? – Šime Vidas Nov 11 '10 at 13:51
  • thats pretty much it, yes. It seems like the JQuery extend function (mentioned in one of the answers will be perfect).. I didnt tag my question with JQuery because I wanted it to be generic, but that function looks like it would work well. – bba Nov 11 '10 at 13:58
  • @bba And you want the new object to also be a property of the instance object ( obj_1 )? – Šime Vidas Nov 11 '10 at 14:00
  • Good question. Doesn't necessarily have to be since I will be operating on the new object inside of this.aMethod. I don't think I'll need it after it returns. So probably the answer is no. – bba Nov 11 '10 at 14:12

4 Answers4

5

Thus spoke Douglas Crockford:

function object (o) {
  function F() {}
  F.prototype = o;
  return new F();
}

There are literally dozens of ways to do that. The videos at Yahoo Theater, and the books Javascript: The Good Parts and Object Oriented Javascript explore some trade-offs. Many javascript libraries implement a simple "class-like" inheritance pattern, but it's just a small piece of the whole cake.

Marco Mariani
  • 13,556
  • 6
  • 39
  • 55
5
SomeObject.prototype.someMethod = function() {

    this.myObject = { key1: 1, key2: 2 };

    this.aMethod = function (o) {
        var newObject = object(this.myObject);

        for (var prop in o) {
            if (o.hasOwnProperty(prop)) {
                newObject[prop] = o[prop];
            }
        }

        // Now newObject contains all properties from the passed in object
        // and also inherits all properties from myObject

    };

};

Note: I am using the object function from @Marco's answer.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Thanks - Ill accept your answer for working with me on this. Is this preferred over simply using the JQuery extend function? – bba Nov 11 '10 at 14:29
  • 1
    @bba I haven't looked into that particular jQuery function yet, but in general I would always prefer jQuery over my own code, since jQuery is thoroughly tested and cross-browser. – Šime Vidas Nov 11 '10 at 14:37
0

If this is what you're looking for:

var Base = function() {
    this.foo = "bar";
};

var MyClass = new Class({ extends: Base }, function() {

    this.myMethod = function() {
        return this.foo; // bar
    }

});

Check this out: Minified 2kb minimalistic library which you can use, https://github.com/haroldiedema/joii/

Harold
  • 1,372
  • 1
  • 14
  • 25
0

this should do the work:

this.aMethod = function(newObject){
  combinedObject = {};
  for(key in this.myObject){
    combinedObject[key] = this.myObject[key];
  }
  for(key in newObject){
    combinedObject[key] = newObject[key];
  }
  return combinedObject;
}

or, if you are using jquery, in one line:

return $.extend({},this.myObject,newObject);
Simon
  • 3,509
  • 18
  • 21
  • Since the OP's code is function code, the this value inside the aMethod function and the this value outside of it don't refer to the same thing, ergo, this.myObject won't give you the object defined earlier in the code. – Šime Vidas Nov 11 '10 at 13:40
  • Sime - do I need to do something like: var self = this, outside of aMethod, and then use self.myObject? – bba Nov 11 '10 at 13:44
  • @bba That would do it. However, the convention is var that = this; and then that.myObject. – Šime Vidas Nov 11 '10 at 13:53
  • @Simon When using for-in loops, it is a good idea to do hasOwnProperty checks so that you don't pick up inherited members... (for example, if the Object.prototype has been augmented). – Šime Vidas Nov 11 '10 at 14:07
  • Correct me if i'm wrong, but I really don't see the problem with the this reference in this code. The this reference inside the method still points to the object that contains the method, which is the same object to which the this reference outside the method points to. The referenced object never changes, when I'm using this code inside of a prototype or constructor function definition. – Simon Nov 11 '10 at 14:22
  • @Sime You're absolutely right concerning the problem with the for-in loop. I didn't think of that since I never would extend Object.prototype to avoid that exact problem. – Simon Nov 11 '10 at 14:25
  • @Simon You're right, my mistake. The aMethod method and the prototype method that contains all the code are both methods of the instance object, so the this value refers to that instance object in both cases. (The difference between those two methods is that one is a direct property of the instance object, and the other one is inherited, but JavaScript has late binding so the this value is in both cases bound to the instance object.) – Šime Vidas Nov 11 '10 at 14:33