• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Objects in javascript

 
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Right now, I'm a bit confused about objects in javascript. so far, I only know of 2 ways to create an object in Javascript:
1. with {} literal
2. with new operator invoked on a function
let's skip arrays for now.

1. so, if I create a new object using {} literal, how would it be different from new() operator?
2. every object has .prototype property that points to its parent object. is this correct? but then again, what about .constructor.prototype property?
3. In Java, Object object is the highest in the object hierarchy. it doesn't have any parent. but in Javascript, Object also has prototype property. How come?
4. there's also [[prototype]], that adds to my confusion.

Thanks
 
Sheriff
Posts: 67749
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:1. so, if I create a new object using {} literal, how would it be different from new() operator?


It isn't. It's shorthand syntax for new Object(). However, you always get an instance of Object. With the new operator, you get to pick other constructors.

2. every object has .prototype property that points to its parent object. is this correct?


No, on two levels. Firstly, only functions have a prototype property. And using the term "parent" is dangerous -- a prototype is not a parent -- it's just an object used a default when an object doesn't have a property.

but then again, what about .constructor.prototype property?


The prototype, as I said above, is only available on functions, so the constructor of the object is what holds the prototype. And the prototype is only significant when the function is used as a constructor.

3. In Java, Object object is the highest in the object hierarchy. it doesn't have any parent. but in Javascript, Object also has prototype property. How come?


Because JavaScript is not Java, and there are no classes in JavaScript. Trying to think of prototypes as superclasses is not correct. Object is the "highest" object. The fact that it has a prototype is irrelevant as, once again, the prototype is in no way a "parent".

4. there's also [[prototype]], that adds to my confusion.


I have no idea what that is.

Immediately stop thinking of a prototype as superclass or parent. The concept is radically different than that. It's just an object that can be used to supply default values for properties that the "primary" object lacks.

Trying to apply the Java class concepts to JavaScript is a huge barrier to understanding how things really work in JavaScript. It's best to not use the term "class" at all, and to never think in terms of parent/child.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wait, so :


is EXACTLY the equivalent of


is this correct?

and, Object() is a function? so basically all objects in JS are created via function? it is basically impossible to construct any object without function?

as for [[Prototype]], I got it from
http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
search for [[Prototype]] in the article. Perhaps you can explain about that?

Many thanks, this revelation just blew my mind. I would've been lost without this understanding, although I'm still trying to process what you said about .prototype and .constructor.prototype.
Thanks
 
Bear Bibeault
Sheriff
Posts: 67749
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:... is EXACTLY the equivalent of ..


Yes.

and, Object() is a function?


In the JavaScript console:


so basically all objects in JS are created via function?


Objects have a constructor.

Perhaps you can explain about that?


Nope. I have no idea what they mean by that notation.

If you have a copy of Secrets of the JavaScript Ninja, chapter 6 might be of interest.
 
Ranch Hand
Posts: 59
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The [[prototype]] notation is from the ECMAScript specification. It is an internal property that exists on every object. The constructor's prototype property is used to set the initial value of [[prototype]]. When the object's properties are accessed, then JS follows the chain of [[prototype]]s until it finds an object that has that property.

It is accessible in browser dependent ways, for example Firefox uses a __proto__ property. See __proto__

Although this should never be manipulated in real code, it can be useful for seeing how objects work in JavaScript.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
so, modifying .prototype property is the recommended way to set up the object chain in javascript? is this approach cross-browser compatible? thanks
 
Bear Bibeault
Sheriff
Posts: 67749
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
why does setting prototype after an object instantiated not alter the object chain? could you please explain this behavior?
thanks
 
Bear Bibeault
Sheriff
Posts: 67749
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not sure what you are asking. Can you illustrate with an example?
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if I create object 1, and then chain it to object 2, I'd get undefined when accessing variables in object 2. But if I chain to object 2 before creating the object 1, I'd be able to access variables in object 2. why is this? thanks
 
author
Posts: 297
5
Android Firefox Browser Fedora
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you mean by "chain object1 to object2"? Why do you think there is an object chain? It seems like you're still trying to do Java objects.
 
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:why does setting prototype after an object instantiated not alter the object chain?



You should not attempt to modify the "implicit" prototype link on a JS object (it's considered bad form). The constructor function automatically initializes the "implicit" prototype link on the JS object under construction - after that the implicit prototype link on the JS object should never change. You can change the "explicit" prototype property on a constructor function. Any subsequently created JS object with that constructor function (using the new operator) will reference that object as its "implicit" prototype.

See also: Item 30: Understand the Difference between prototype, getPrototypeOf, and __proto__
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, that's what I tried to do. so, when I instantiate object 1 and change the "explicit" prototype property, the change is not reflected on object 1. This is what confused me. thanks
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:when I instantiate object 1 and change the "explicit" prototype property



Only function objects are supposed to have an "explicit" prototype property. __proto__ on general JS objects is a hack. To get an object's prototype object use Object.getPrototypeOf.



See also: Object.getPrototypeOf
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if


comes before


then


would return undefined.
This is what I'm asking.
Thanks
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Of course it is. Changing the prototype on the constructor function object only effects the objects that it will initialize from that point on - NOT objects that have already been initialized.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
so, how do you explain this phenomenon? what's actually happening behind the scene? if I use Java mindset (I know, this is Javascript, not Java, but I'm Java dev, so....), everything is passed by ref, so, my code should've worked. thanks
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:if I use Java mindset



You have got to let go of that to deal with JavaScript in the correct way. In any case you are modifying the prototype property of the function object that is acting as a constructor. BUT the constructor is IS NOT A CLASS. It simply initializes objects when the new operator is used.
So if you set constructor.prototype = proto1 all constructed objects from this point on will implicitly link to proto1 as their prototype. But then later you change constructor.prototype = proto2 - now any NEW objects will implicitly link to proto2 as their prototype - BUT all the old ones (before the change) are still implicitly linked to proto1. Therefore none of the "old" objects can see properties on proto2.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
okay, but could you explain why this is happening? what is the mechanism behind this ? thanks
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Using an object literal {}does not in fact invoke the Object constructor and is usually a tiny bit faster than using new Object(),

[[prototype]] refers to the hidden property in every object, .__proto__ which refers to the objects prototype
By default object literals inherit directly from Object.prototype

The constructor property isn't something to rely on being there either because it's not created in Object.create() or if you assign a new object to a constructors prototype property
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:I'm a bit confused about objects in javascript



In terms of capabilities "from the Java perspective" JS objects are totally misnamed. The dot-notation

is syntactic sugar for

which exposes the true nature of the JS object - a collection of key-value pairs, a glorified hash table - that's it.
The most basic instance of a "hash table" is constructed with the 'Object' function object - so all these "hash tables" are referred to as "JavaScript objects".

Most introductions make a big deal of stating that "in JavaScript functions are first class objects" - they don't go far enough - "in JavaScript function objects are THE first class object". Arrays and "JavaScript objects" are just the function object's little helpers. Its also best to stop thinking about "functions" but instead always think of "function objects".

Coming from Java 'this' isn't what you think - in JavaScript 'this' is the "function context". Again object dot-notation

is syntactic sugar for

which is equivalent to

  • object['f'] accesses the reference to the function object that is stored in the 'f' property of 'object'.
  • all function objects support the apply method - the first parameter is what is accessed with 'this' inside the function code, the second is just an array with the function arguments (not an array inside of the function code - but that is another story).

  • So when we are talking about "methods" on "JavaScript objects" we are still just talking about "plain old" properties on a hash table that happen to have a function object reference as a value. The JavaScript environment just conveniently specifies the object the reference is stored in as the "function context".

    There is no universal 'prototype' property on "JavaScript objects". Each "JavaScript object" has an implicit reference to a "prototype object" which is set on the "JavaScript object" by the JavaScript environment before the code inside the constructor function can initialize the new "JavaScript object". The JavaScript environment takes the object reference in the constructor function object's 'prototype' property to initialize the "JavaScript object's" prototype link - after that point the prototype link for that particular object will never change (ideally). So later changes to the 'prototype' property of the constructor function object will not affect "JavaScript objects" that already exist.

    It's best to view the prototype chain as a reuse/sharing mechanism. "JavaScript objects" sharing the same prototype don't need to duplicate property values (and therefore function objects or function object references). The properties that you can access are a union of all the properties found on all the objects along the prototype chain. BUT you can only mutate properties on the actual object - so when you set an identically named property on an object, the same property (and its value) continues to exist on the chain but is now hidden from access (but still accessed by other objects sharing the prototype).

     
    Peer Reynders
    Bartender
    Posts: 2968
    6
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    David Spades wrote:what is the mechanism behind this?



    I think that you may be getting confused with the levels of indirection (in C/C++ typically identified as "pointer confusion").

    Contrast the following two scenarios:

    Above an entirely different object is set on myConstructor.prototype between the creation of objTom and objHarry. So each of them are referring to entirely different objects as their prototype.


    In this second scenario only a property of the constructor's prototype property was changed. Therefore both objTom and objHarry use the same prototype object - this also explains why the behaviour of objTom.f1() changes after the prototype object is updated.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic