This works, though I've not seen object literals as prototypes in any other code. Is there a reason for this? This seems like a logical way of coding to me though I don't want to pursue it if it has serious pitfalls.

Well, anyone can swap literal.init with whatever they feel like, and the change will reflect on every instance ever created. This would not be possible if there was no intermediate literal stage.
–
JonMay 29 '13 at 13:07

@jon I understand that, I guess I really want to know if using literals as prototypes is, for lack of other words, 'ok' :-)
–
David BarkerMay 29 '13 at 13:09

1

I would say that like nearly everything in JavaScript, prototype is just an object and can therefore be created or reassigned like any other object. I have seen this pattern quite a few times but I'm also curious if this has some disadvantages. I would say 'no' ...but good question.
–
basilikumMay 29 '13 at 13:09

4 Answers
4

It's perfectly normal to use an object literal to create the prototype for a function, but normally only as the actual value of the prototype object.

What's unusual is doing what you've done and include a nested object within the prototype.

In effect you've only added one object to the prototype, the one named literal. All of the methods are then properties of that object. It's technically valid syntax, but I've never seen it used before. As @squint points out in the comments, it also appears to break the way that the this variable works, because it binds this to the "next left" property that was used in the function call:

actually it really was only an example, I would intend to have either multiple nested objects as prototypes or a mixture of nested objects and function prototypes. Thanks for the answer this was the sort of clarification I was looking for.
–
David BarkerMay 29 '13 at 13:52

As for edit, yes this is exactly what I would have expected without calling the object with a context. Thanks again.
–
David BarkerMay 29 '13 at 13:53

@DavidBarker yup - don't nest properties in the prototype. It breaks things in unexpected ways. In the example I did call it with a context, but that context was inst.literal, and not inst. I'm a pretty experienced JS programmer and that caught me out.
–
AlnitakMay 29 '13 at 13:54

Yes, that is a concern and could cause problems down the line with readability and mind bending contextual changes. I think I'll stick to splitting out the nested literal either as a stand-alone literal or class prototype.
–
David BarkerMay 29 '13 at 14:01

@DavidBarker splitting it out (and storing a reference to it in the prototype) won't help - there's simply no good reason to put nested properties in the prototype.
–
AlnitakMay 29 '13 at 14:04

Some explanation: Value of prototype is an object. It doesn't matter how the object was created - using simply {} is fine. It is often initialized using something like MyClass1.prototype = new MyClass2(), but newjust creates a new object. It also sets the prototype property and executes the constructor (MyClass2) but on the new object, it doesn't affect MyClass1 in any way (see explanation here).

Using a nested literal doesn't make a difference. In the question, the prototype is set to { literal : { ... } }. What actually happens when you call inst.literal.init() is:

The runtime looks at inst and checks whether the object has a value assigned for property literal.

inst dos not have such property, therefore the runtime continues with its prototype property

inst.prototype references the literal object to which it was initialized. This object has assigned a value for property literal.

What you are doing is setting the prototype to be a JavaScript object with several properties. This is perfectly acceptable, as functions act very similarly to objects in JavaScript. All JavaScript does is passes the reference to this prototype property down to inherited objects, so they will not have a function they can access, but an object instead in this case.

Are you splitting hairs between object literal and JavaScript Object Literal? And besides, it's still not JSON, so your link is misleading.
–
MathleticsMay 29 '13 at 13:44

1

@AlexW: Forget the "JS" in "JSON". It's merely a nod to the literal syntax that was partially used in forming the JSON syntax. JSON is a data transmission format. It doesn't make sense to refer to object literal syntax in a JavaScript program as JSON since you can't directly use the result of the syntax for data transmission.
–
squintMay 29 '13 at 13:51

1

I write them exactly as they are, object literals. @squint beat me to a perfect reply, but you are welcome to read the spec.
–
MathleticsMay 29 '13 at 13:52