Adding Prototype to JavaScript Object Literal
Asked Answered
C

6

62
STORE = {
   item : function() {
  }
};
STORE.item.prototype.add = function() { alert('test 123'); };
STORE.item.add();

I have been trying to figure out what's wrong with this quite a while. Why doesn't this work? However, it works when I use the follow:

STORE.item.prototype.add();
Comestible answered 20/10, 2009 at 4:9 Comment(0)
E
93

The prototype object is meant to be used on constructor functions, basically functions that will be called using the new operator to create new object instances.

Functions in JavaScript are first-class objects, which means you can add members to them and treat them just like ordinary objects:

var STORE = {
   item : function() {
  }
};

STORE.item.add = function() { alert('test 123'); };
STORE.item.add();

A typical use of the prototype object as I said before, is when you instantiate an object by calling a constructor function with the new operator, for example:

function SomeObject() {} // a constructor function
SomeObject.prototype.someMethod = function () {};

var obj = new SomeObject();

All the instances of SomeObject will inherit the members from the SomeObject.prototype, because those members will be accessed through the prototype chain.

Every function in JavaScript has a prototype object because there is no way to know which functions are intended to be used as constructors.

Ellga answered 20/10, 2009 at 4:15 Comment(2)
We can also assign prototype like so Object.create(prototype). More info here.Fictive
In other words, only objects which have been created using the constructor function (with the 'new' keyword) have access to the properties and function defined in the prototype. Starting from the question in the example, this will work: var storeItem = new STORE.item() storeItem.add();Biretta
M
21

After many years, when JavaScript (ES2015 arrives) we have finally Object.setPrototypeOf() method

const STORE = {
  item: function() {}
};


Object.setPrototypeOf(STORE.item, {
  add: function() {
    alert('test 123');
  }
})


STORE.item.add();
Mossgrown answered 19/4, 2016 at 11:45 Comment(2)
When this becomes valuable in the sense of searching the chain?Profundity
Hi @serkan, could you clarify your question a little more? I'm not sure what you meant.Jacquejacquelin
F
5

As of this writing this is possible by using the __proto__ property. Just in case anyone here is checking at present and probably in the future.

const dog = {
    name: 'canine',
    bark: function() {
        console.log('woof woof!')
    }
}

const pug = {}
pug.__proto__ = dog;

pug.bark();

However, the recommended way of adding prototype in this case is using the Object.create. So the above code will be translated to:

const pug = Object.create(dog)

pug.bark();

Or you can also use Object.setPrototypeOf as mentioned in one of the answers.

Hope that helps.

Fictive answered 28/9, 2016 at 10:3 Comment(1)
Using this method to add functions to the prototype ended up causing me some unintended consequences. It actually messed up some other functions in the project. I don't yet know why because I just added the functions as properties of the object instead of in the prototype. (I was doing everything to an object literal, rather than a constructor.)Elmerelmina
E
3

You can use JSON revivers to turn your JSON into class objects at parse time. The EcmaScript 5 draft has adopted the JSON2 reviver scheme described at http://JSON.org/js.html

var myObject = JSON.parse(myJSONtext, reviver);

The optional reviver parameter is a function that will be called for every key and value at every level of the final result. Each value will be replaced by the result of the reviver function. This can be used to reform generic objects into instances of pseudoclasses, or to transform date strings into Date objects.

myData = JSON.parse(text, function (key, value) {
    var type;
    if (value && typeof value === 'object') {
        type = value.type;
        if (typeof type === 'string' && typeof window[type] === 'function') {
            return new (window[type])(value);
        }
    }
    return value;
});
Ex answered 20/10, 2009 at 5:12 Comment(1)
Good to know this information. +1. A little more detailed example with myJSONtext and type function details would have been even better but anyway thanks for this info!Trix
B
2
STORE = {
   item : function() {
  }
};

this command would create a STORE object. you could check by typeof STORE;. It should return 'object'. And if you type STORE.item; it returns 'function ..'.

Since it is an ordinary object, thus if you want to change item function, you could just access its properties/method with this command.

STORE.item = function() { alert('test 123'); };

Try STORE.item; it's still should return 'function ..'.

Try STORE.item(); then alert will be shown.

Barimah answered 23/6, 2019 at 15:9 Comment(0)
H
0

The __proto__ (further to JohnnyQ's response) can be specified right on the literal declaration, additional prototypes can be mixed together using assign to inherit from multiple parent prototypes:

const dog = {
    makeNoise: function () {
        console.log('woof woof!')
    }
}

const owned = {
    ownedBy: function () {
        console.log('chad')
    }
}

const pet = {
    __proto__: Object.assign({}, dog, owned)
};

pet.makeNoise();
pet.ownedBy();
Helminthic answered 1/7 at 19:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.