...

View Full Version : A little confused about Objects



javanewbie7
12-04-2012, 03:39 AM
So I'm reading a book on Javascript trying to get a better understanding of it all. But I've become stuck on Objects. Seeing how js is an Object Oriented language, I'm stopping on this chapter until I fully understand it. There's not one particular part that I find confusing, but it's more that I'm not understanding how I would use something like the Constructor Pattern or getOwnPropertyDescriptor().

I've looked around the internet to find a better description, but no luck so far. Is there a good tutorial somewhere that you guys would recommend? Or could someone at least give an example of how I would use said objects?

The book (so far) has been really good. But I find the examples in this section to be vague. (It's using getting a person's name, age, job). In real life javascript, what would I use it for. I think seeing a good example would help me a lot.

Thanks

Dormilich
12-04-2012, 11:28 AM
Constructor Pattern? or do you mean how objects are created through Constructors?

getOwnPropertyDescriptor() is somewhat easier. in ECMAScript 262 edition 5, there were property descriptors introduced, which allow a certain amount of property configuration (e.g. property is not writeable). see also https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty. getOwnPropertyDescriptor() just gives you access to those descriptors.

Old Pedant
12-04-2012, 07:35 PM
It might be helpful to understand JSON-style object definitions first.

For example:


var john = {
name : "John Doe",
email : "john@xyz.com",
title : "Chief Gofer"
};

Do you understand that? That says "create an object, referenced by the variable john, with the properties shown. To wit, name and email and title properties.

Once you have done that, you can then use code such as

someHTMLelement.innerHTML = john.email;

or (unlikely, but possible)

if ( john.title == "Chief Gofer" ) { ... do something ... }


Now, that notation is great for creating fixed (or semi-fixed) objects, but it's a little less usable if you need to create a great number of people, isn't it?

So we introduce constructors:


function Person( nm, em, ttl )
{
this.name = nm;
this.email = em;
this.title = ttl;
}

and then we can create john thus:


var john = new Person( "John Doe", "john@xyz.com", "Chief Gofer" );

and at this point, those two john objects are completely equivalent!

So a constructor might be thought of as being a "factory" to create many objects of the same kind, each with different content.

Constructor notation is about as close as JavaScript comes to matching syntax with other languages (esp. Java and C++) that are class-based and use constructors to create instances of classes. JavaScript doesn't have classes in the same way such more conventional languages do, but it does have objects that, in most ways, act the same way objects in those languages do.

[The big difference: JavaScript objects are mutable, whereas C++ and Java objects are not. That is, you can add properties and methods to any JavaScript object at any time. In Java and C++ you can only do so by modifying the class--and recompiling your entire program or set of programs. For example, in JavaScirpt I can use that constructor above and then add to the object. Such as

var john = new Person( "John Doe", "john@xyz.com", "Chief Gofer" );
john.phone = "8005551212";
john.prettyPhone =
function()
{
var p = this.phone;
return "(" + p.substr(0,3) + ") " + p.substr(3,3) + "-" + p.substr(6);
};
alert( john.prettyPhone( ) );

No way to do that second step in conventional languages, let alone the 3rd and 4th ones.

rnd me
12-04-2012, 08:56 PM
[The big difference: JavaScript objects are mutable, whereas C++ and Java objects are not. That is, you can add properties and methods to any JavaScript object at any time.

yes, but not always. let's be modern and comprehensive here since the OP did mention property descriptors...

you can freeze an object, or use Object.definePoperty() to create non-writable and non-delete-able properties.

for example, an employee can change their name, but not a company-assigned ID#:



var john = {
name : "John Doe",
email : "john@xyz.com",
title : "Chief Gofer"
};

Object.defineProperty(john, "id", "abc");

delete john.id;
john.id=123;
alert(john.id); //shows "abc";

Dormilich
12-04-2012, 08:57 PM
… or non-enumerable or even properties that are defined by getters and setters (instead by simple values).

felgall
12-04-2012, 09:18 PM
There are lots of different ways to create objects in JavaScript.

Another useful one that hasn't been mentioned yet in this thread is to use the static method Object.create()

Old Pedant
12-04-2012, 09:33 PM
All the above true. I wasn't trying to be comprehensive.

One thing none of us mentioned but that tends to confuse the heck out of people new to this stuff:

Variables are *NOT* and *CAN NOT* be objects!

Variables *CAN* be (and commonly are) *REFERENCES* to objects.

I was careful in my prior post when I wrote

Do you understand that? That says "create an object, referenced by the variable john, with the properties shown.

Even when we do

var john = new Person("john doe","john@xyz.com","Chief Gofer");
or even if we were to write (legal code!)

var object = new Object( );

those variables (john and object) are *NOT* objects. They are REFERENCES to objects.

It's a very important distinction! If I now write

var jane = john;
jane.name = "Jane Roe";
alert( john.name );

I will find that john has changed his name to Jane Roe!!!

Because all that var jane = john did was copy the *reference* to the object. So we ended up with two references to the same object.

So don't mistake references for actual objects. We treat them much the same, but they aren't the same.

********************

FWIW, this same distinction applies in Java and C# and, for the most part, in C++. (There are ways for a variable to actually *BE* an object in C++. Not commonly used, but...)

felgall
12-04-2012, 09:55 PM
Variables are *NOT* and *CAN NOT* be objects!

Variables *CAN* be (and commonly are) *REFERENCES* to objects.

Just to expand on this - it is possible to copy objects in JavaScript but it requires a few more lines of code compared to simply setting up another reference.


deepCopy = function(p,c) {
var c = c||{};
for (var i in p) {
if ('object' === typeof p[i]) {
c[i] = (p[i].constructor === Array)?[]:{};
deepCopy(p[i],c[i]);
} else c[i] = p[i];}
return c;
}

var john = new Person("john doe","john@xyz.com","Chief Gofer");
var jane = deepCopy(john);
jane.name = "Jane Roe";

With this code john and jane are references to different objects both of which have all the same properties and methods with only the name property having a different value between the two separate copies of the oblect. The copy is made by creating a new object and then copying the properties and methods across one by one using recursive calls as necessary to work down to elements that can actually be directly accessed rather than just referenced.

rnd me
12-05-2012, 05:51 AM
Just to expand on this - it is possible to copy objects in JavaScript but it requires a few more lines of code compared to simply setting up another reference.

The copy is made by creating a new object and then copying the properties and methods across one by one using recursive calls as necessary to work down to elements that can actually be directly accessed rather than just referenced.

doesn't always work.

for example:


var john = new RegExp("hello world")
var jane = deepCopy(john);
jane.name = "Jane Roe";
[jane, john] // ==[ {name : "Jane Roe"}, /hello world/]


for generic objects it works just fine, but if you don't need methods, you can deep copy using native JSON instead of loops:


jane=JSON.parse(JSON.stringify( john ));

which is much faster than user-land looping and recursive calls.


if you want to take your core to the max, a few minor adjustments are needed to make it more like the structured clone algorithm than JSON.stringify():



function deepCopy(orig, update) {
var key, val, copy = update || new orig.constructor(orig.valueOf());

for (key in orig) {
val = orig[key];
copy[key] =( val instanceof Object ) ?
deepCopy ( val, val.constructor() ) :
val ;
} /* next */

return copy;
} /* end deepCopy() */

using constructors instead of sniffing types means it works for more than Arrays and generic Objects:


var john = new RegExp("hello world")
var jane = deepCopy(john);
jane.name = "Jane Roe";

[jane, john]+'' // == [/hello world/,/hello world/]



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum