Extending prototype on object literal
Asked Answered
M

3

0

If I have the following code, why does it return an error saying Cannot set property 'second_prop' of undefined . I thought that you can extend the prototype property and add more variables and methods to the object prototype. Since the two console statements return 'Object' and true, then why does it return an error of undefined. My thinking is, if the 'obj' is an object of type Object, then I should be able to do temp.prototype.newproperty? So then the Object will have a 'newproperty'. But I'm obviously wrong, so there's something I am missing here. Even more, why do I need to do Object.create() when the obj is already an object literal? Isn't it already an object? I'm just looking at some examples and trying to understand this

    var obj = {
        first_property: 'first property'
    }
    console.log(typeof obj);
    console.log(obj instanceof Object);

    var temp = Object.create(obj);
    temp.prototype.second_prop = 'second property'

Output

//object
//true
//Uncaught TypeError: Cannot set property 'second_prop' of undefined

So, why can't i do temp.prototype or obj.prototype?

Mel answered 30/4, 2015 at 21:16 Comment(3)
Only constructor functions do have a .prototype property. What are you actually trying to do?Quill
I answered a similar question earlier today, hope this is helpful: https://mcmap.net/q/1175047/-difficulty-manually-walking-the-prototype-chainAcidic
Does this answer your question? Extending object literalPajamas
M
2

If I have the following code, why does it return an error saying Cannot set property 'second_prop' of undefined

A Javascript literal object is already an instantiated Object and does not have the .prototype property. That property is on a constructor function, not an already instantiated object. In any current browser (IE9+), you can use Object.getPrototypeOf() to obtain the prototype for an already built object.

But, it sounds more like you'd rather just clone an object and then add properties to the clone. Or if you want both objects to have the same additional property, then add the property, then clone it. Or, if you just want to use your literal object, then just use it as it is.

Once an object has already been constructed, the prototype is an internal property and it is generally not meant for you to be messing with it. If you intend to change the prototype for all objects, you should be changing the prototype on the constructor. If you meant to be changing properties for just this instance of the object, then just change properties on the object itself, not the prototype.

As always, if you describe what you're actually trying to accomplish (rather than why your own solution does not do what you expected), we can help you much better.

I thought that you can extend the prototype property and add more variables and methods to the object prototype.

You can, but the .prototype property is on a constructor, not on an already built object.

Since the two console statements return 'Object' and true, then why does it return an error of undefined. My thinking is, if the 'obj' is an object of type Object, then I should be able to do temp.prototype.newproperty?

You are confusing being an instantiated object with being a constructor with a prototype. An instantiated object has a prototype as an internal property, not as a public .prototype property. So, when something reports instanceof, that means it is literally an instance of that type of object (and thus has that type of objects prototype in its internal prototype chain), not that it's a constructor with the public .prototype property.

Even more, why do I need to do Object.create() when the obj is already an object literal? Isn't it already an object?

The purpose of Object.create() is to create a new object, using an existing object as the prototype. If you're declared a Javascript literal and you just want to use the literal as an object by itself, then there is NO reason to use Object.create() on it. Just use the literal as the already built object that it is.

Messinger answered 30/4, 2015 at 21:18 Comment(4)
Let's say "normal" browsers these days :-) "Newer" browsers would implement Reflect.setPrototypeOf (ES6), only old browsers do not support ES5.Quill
@Quill - I made the reference more specific (IE9+). Even ES6 browsers will support Object.getPrototypeOf(), right?Messinger
Yes, ES6 is backwards-compatible so they will implement ES5 Object.getPrototypeOf for sure.Quill
@Mel - I've added lots more detail to my answer to address the various pieces of your question. Let me know if you still need any more explanation.Messinger
R
0

temp doesn't have a prototype. Object has a prototype. You can change the prototype for all Objects by calling Object.prototype but you can't change it for just once object.

Revitalize answered 30/4, 2015 at 21:19 Comment(11)
It does have a prototype (obj), but not a .prototype property.Quill
temp does inherit from obj which does inherit from Object.prototype which does inherit from nullQuill
@Quill in your console, do var temp = Object.create({}) Then try and call temp.prototype. You will see it does not exist. Now, you could create it if you wanted to... you could do temp.prototype = {}; temp.prototype.second_prop = 'second_property'; but it will behave like a normal object key, not like the actual Object prototypeRevitalize
@Quill temp inherits nothing. It is a reference, not an extension of Object itself.Revitalize
@MatthewHerbst: I didn't say there was a temp.prototype, I did say that the temp object does have a prototype - which is obj. Because that's how Object.create works…Quill
@Quill test it out in your javascript console in your web browser. That's not what's happening.Revitalize
@MatthewHerbst: For sure it is (I don't need to test this). Try obj = {}; temp = Object.create(obj) yourself and closely inspect the result.Quill
@Quill I'm not going to keep repeating myself. Based on your last comment, try doing temp.prototype. You will see it doesn't exist. The prototype is part of the Object construction. So again, you can create the prototype if you want by doing temp.prototype = {} and then doing temp.prototype.second_prop = "second_property";Revitalize
Of course it doesn't exist! I never said otherwise, and I'm not going to repeat that. Please re-read my comments.Quill
Then what exactly is your question? Do you want to know why your code fails or why temp does inherit from Object? The two are very different questions.Revitalize
@MatthewHerbst: I didn't ask a question, I tried to help clarifying.Quill
A
0

.prototype is a property that is not allways linked to the actual prototype of the object. The real prototype can be accesed via .__proto__

var obj = {
    first_property: 'first property'
}
console.log(typeof obj);
console.log(obj instanceof Object);

var temp = Object.create(obj);

temp.__proto__.second_prop = 'second property';

console.log(Object.getPrototypeOf(temp));

//{ first_property: 'first property',
//second_prop: 'second property' }
Autolithography answered 30/4, 2015 at 21:36 Comment(1)
Better use only Object.getPrototypeOf, and never mention __proto__ at all.Quill

© 2022 - 2024 — McMap. All rights reserved.