Advanced javascript - can anyone explain this intricacy?

F

Faisal Vali

Hi - I'm new to javascript and I was reading the book Javascript
Professional Projects - there is a fragment that has me a little
perplexed, and I was wondering if anyone could explain why and how it
works.
How is it that setting a property to null alters another property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

Can you attach "hooks" in javascript that get called whenever a
property is modified?
Or does an eventhandler get triggered behind the scenes that updates
selectedIndex - and if so - how do i attach similar eventhandlers to
objects - or is this an intrinsic feature of javascript?

Here is the function. I have inserted some debug messages which
illustrate that as soon as the property is set to null -
fromSelect.selectedIndex gets updated.


function swapSelects( fromSelect, toSelect )
{
var toSelect_Length = toSelect.options.length;
while( fromSelect.selectedIndex > -1 )
{
var index = fromSelect.selectedIndex;
alert( "1>" + fromSelect.selectedIndex );
toSelect.options[toSelect_Length] = new Option(
fromSelect.options[index].text );
toSelect.options[toSelect_Length].value =
fromSelect.options[index].value;
alert( "2>" + fromSelect.selectedIndex );

// note this is the line that triggers the update
fromSelect.options[index] = null;
alert( "3>" + fromSelect.selectedIndex );

toSelect_Length++;
}

thanks in advance.
Faisal Vali.
 
J

Jake Barnes

Faisal said:
Hi - I'm new to javascript and I was reading the book Javascript
Professional Projects - there is a fragment that has me a little
perplexed, and I was wondering if anyone could explain why and how it
works.
How is it that setting a property to null alters another property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

I've tried to recreate this, but I can not. Please see the code on this
page:

http://www.krubner.com/testJavascript.htm
 
J

Jake Barnes

Faisal said:
Hi - I'm new to javascript and I was reading the book Javascript
Professional Projects - there is a fragment that has me a little
perplexed, and I was wondering if anyone could explain why and how it
works.
How is it that setting a property to null alters another property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

You'll note that in the experiment that I posted here:

http://www.krubner.com/testJavascript.htm

things work as you would expect: it is the value that becomes null, not
the index.

I'm not clear on how you concluded that "How is it that setting a
property to null alters another property?"

I don't see that happening.
 
J

Jake Barnes

Faisal said:
Here is the function. I have inserted some debug messages which
illustrate that as soon as the property is set to null -
fromSelect.selectedIndex gets updated.


function swapSelects( fromSelect, toSelect )
{
var toSelect_Length = toSelect.options.length;
while( fromSelect.selectedIndex > -1 )
{
var index = fromSelect.selectedIndex;
alert( "1>" + fromSelect.selectedIndex );
toSelect.options[toSelect_Length] = new Option(
fromSelect.options[index].text );
toSelect.options[toSelect_Length].value =
fromSelect.options[index].value;
alert( "2>" + fromSelect.selectedIndex );

// note this is the line that triggers the update
fromSelect.options[index] = null;
alert( "3>" + fromSelect.selectedIndex );

toSelect_Length++;
}

I'm trying to make this function work on this page:

http://www.krubner.com/testJavascript.htm

The code is dying on the line where you reference fromSelect.options.
It is hard for me to imagine what kind of parameters you're trying to
pass in to this function. The parameters seem to be complex objects
that are both arrays themselves and also contain arrays. Had you gone
into more detail, that would have been helpful. I tried to guess what
kind of objects you were using as parameters, but I've given when I
realized the complexity of these things.

For now I get this error:

Error: fromSelect.options has no properties


Please note, I also had to explicitly assign a value of "0" to
fromSelect.selectedIndex to get even as far as I did.
 
R

Richard Cornford

Faisal said:
Hi - I'm new to javascript and I was reading the book
Javascript Professional Projects - there is a fragment
that has me a little perplexed, and I was wondering if
anyone could explain why and how it works.

How is it that setting a property to null alters another
property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

There was once a time when the browser's object model and JavaScript(tm)
where virtually the same thing. Standardisation has acted to separate
the two, and we now have a core language (specified by ECMA 262 3rd
Edition), vendor specific extensions to that language, and the object
model provided by the host of the scripts. This allows a standardised
javascript to be used for scripting more types of host than just web
browser (such as PhotoShop from version 7).

Assuming the above - optionObject - is a reference to the DOM
representation of an HTML SELECT element (which is necessary to explain
the phenomenon described) the behaviour of the object when it is
modified is not determined by javascript at all. It is what is
classified as a "host object", and so is not part of the language.

For the DOM representation of a SELECT element (without the MULTIPLT
attribute) the - selectedIndex - property is the index value of the
currently selected OPTION element. The act of assigning - null - to a
member of the SELECT element's - options - collection is to remove that
OPTION element from the SELECT element. And if you remove the currently
selected OPTION element it can no longer be the currently selected
OPTION element, so the - selectedIndex - property of the SELECT element
must be changed.

As an OPTION element should not become selected unless the user selects
it the - selected Index - property must be set to a value that is not an
index of an OPTION element, and one that can be used to signal to
scripts that no OPTION element is selected. The value of -1 is used for
that purpose.
Can you attach "hooks" in javascript that get called
whenever a property is modified?
<snip>

In the standardised core of javascript you cannot. As a result it is
extremely unlikely that cross-browser code would ever attempt to do so.
However, some implementations have a - watch - extension that could be
used in that way, and the JavaScript(tm) implementation has -
__defineGetter__ - and - __defineSetter__ - extension that can allow
code to react to property changes. JScritp in IE has none of these, but
some of the IE browser's host objects support an - onpropertychange -
event handler that can be triggered by some property changes.

For pure javascript objects it is possible to adopt a design pattern
that provides 'setter' functions and insists that they are exclusively
used to set the values of properties. This allows side-effect code to be
triggered in response to changes in those property values, and it is
possible to then implement event handlers on javascript objects and have
them triggered by the side-effect code in the 'setters'.

Richard.
 
J

Jake Barnes

Faisal said:
Can you attach "hooks" in javascript that get called whenever a
property is modified?
Or does an eventhandler get triggered behind the scenes that updates
selectedIndex - and if so - how do i attach similar eventhandlers to
objects - or is this an intrinsic feature of javascript?

I don't believe there is an event handler for a change of properties,
though you could use javascript closures to enforce such a thing:

objectForSettingUserNumbers = function setNumberOfUsers(numberOfUsers)
{
var howManyUsersOnThisPage = 0;

var controllerForHowManyUsers = function(users) {
howManyUsersOnThisPage = users;
alert("howManyUsersOnThisPage now equals " +
howManyUsersOnThisPage);
}

controllerForHowManyUsers(numberOfUsers);
return controllerForHowManyUsers;
}



This sets howManyUsersOnThisPage to 8 :

objectForSettingUserNumbers(8);


The variable howManyUsersOnThisPage is now completely encapsulated,
like a private class variable in any object oriented language - there
is no way to reach it accept through the method we've allowed. Thus,
yes, here you could set triggers that go off whenever someone tries to
reach this value.

I put this code up on the same test page as before:

http://www.krubner.com/testJavascript.htm
 
J

Jake Barnes

Jake said:
I don't believe there is an event handler for a change of properties,
though you could use javascript closures to enforce such a thing:


Actually, this would be more flexible than my first example:

function setNumberOfUsers()
{
var howManyUsersOnThisPage = 0;

var controllerForHowManyUsers = function(users) {
howManyUsersOnThisPage = users;
alert("howManyUsersOnThisPage now equals " +
howManyUsersOnThisPage);
}
return controllerForHowManyUsers;
}


objectForSettingUserNumbers = setNumberOfUsers();

Now objectForSettingUserNumbers is a reference to the anonymous
function stored in controllerForHowManyUsers. You can continue to
change the value of howManyUsersOnThisPage, but only using this one
method:

This sets howManyUsersOnThisPage to 8 :

objectForSettingUserNumbers(8);

or 18:

objectForSettingUserNumbers(18);
 
T

Tom Cole

Faisal said:
Hi - I'm new to javascript and I was reading the book Javascript
Professional Projects - there is a fragment that has me a little
perplexed, and I was wondering if anyone could explain why and how it
works.
How is it that setting a property to null alters another property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

Can you attach "hooks" in javascript that get called whenever a
property is modified?
Or does an eventhandler get triggered behind the scenes that updates
selectedIndex - and if so - how do i attach similar eventhandlers to
objects - or is this an intrinsic feature of javascript?

Here is the function. I have inserted some debug messages which
illustrate that as soon as the property is set to null -
fromSelect.selectedIndex gets updated.


function swapSelects( fromSelect, toSelect )
{
var toSelect_Length = toSelect.options.length;
while( fromSelect.selectedIndex > -1 )
{
var index = fromSelect.selectedIndex;
alert( "1>" + fromSelect.selectedIndex );
toSelect.options[toSelect_Length] = new Option(
fromSelect.options[index].text );
toSelect.options[toSelect_Length].value =
fromSelect.options[index].value;
alert( "2>" + fromSelect.selectedIndex );

// note this is the line that triggers the update
fromSelect.options[index] = null;
alert( "3>" + fromSelect.selectedIndex );

toSelect_Length++;
}

thanks in advance.
Faisal Vali.

In javascript -1 equates to null, and null can equate to false.

What happens is you set the selected object to a null, so when you ask
it for the selected index, it returns you -1 (null which will also
equate to false).
 
R

RobG

Tom said:
Faisal said:
Hi - I'm new to javascript and I was reading the book Javascript
Professional Projects - there is a fragment that has me a little
perplexed, and I was wondering if anyone could explain why and how it
works.
How is it that setting a property to null alters another property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.
[...]

In javascript -1 equates to null, and null can equate to false.

What happens is you set the selected object to a null, so when you ask
it for the selected index, it returns you -1 (null which will also
equate to false).

You should have read Richard's response. An HTML select element is not
a built-in JavaScript object, it is provided by the host environment.
In most browsers, its behaviour conforms to the W3C DOM HTML
specification which says that if no option is selected, the
selectedIndex property should return -1.

<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-85676760 >

In JavaScript, -1 is not equivalent to 'null'. When evaluated in a
conditional expression it is type converted to boolean true. According
to the ECMAScript Specification section 9.2, the numbers +0, -0 and NaN
type convert to false, any other number converts to true.

Try it:

alert( !!(-1) ); // Shows true


The fun part here is working out what should happen when the
selectedIndex property is set to null. According to the W3C
specification, the selectedIndex property is a long, which in
JavaScript equates to a number primitive. When converting 'null' to a
number using toNumber, null should be converted to +0.

It might therefore be argued that assigning null to the selectedIndex
property should result in it being set to +0, thereby making the first
option selected. Clearly that logic is flawed... :)
 
R

Richard Cornford

RobG said:
Tom Cole wrote:
In JavaScript, -1 is not equivalent to 'null'. When evaluated in a
conditional expression it is type converted to boolean true.
It might therefore be argued that assigning null to the selectedIndex
property should result in it being set to +0, thereby making the first
option selected. ...

Fortunately the posted code never did assign null to the -
selectedIndex - property so null's type-converting to numeric zero is
not significant.

Richard.
 
F

Faisal Vali

Dear Richard - thank you very much for your insightful and helpful
answer - I do have some comments/questions.

Richard said:
Faisal said:
<snip> >
How is it that setting a property to null alters another
property?
For example setting
optionObject.options[optionObject.selectedIndex] = null;
seems to set optionObject.selectedIndex to -1 automagically.

There was once a time when the browser's object model and JavaScript(tm)
where virtually the same thing. Standardisation has acted to separate
the two, and we now have a core language (specified by ECMA 262 3rd
Edition), vendor specific extensions to that language, and the object
model provided by the host of the scripts. This allows a standardised
javascript to be used for scripting more types of host than just web
browser (such as PhotoShop from version 7).

aah - ok that does explain the phenomenon that i found perplexing.
Assuming the above - optionObject - is a reference to the DOM
representation of an HTML SELECT element (which is necessary to explain
the phenomenon described) the behaviour of the object when it is
modified is not determined by javascript at all. It is what is
classified as a "host object", and so is not part of the language.

Your assumption/intuition is indeed correct and the arguments do refer
to an HTML SELECT element.
For the DOM representation of a SELECT element (without the MULTIPLT
attribute) the - selectedIndex - property is the index value of the
currently selected OPTION element. The act of assigning - null - to a
member of the SELECT element's - options - collection is to remove that
OPTION element from the SELECT element. And if you remove the currently
selected OPTION element it can no longer be the currently selected
OPTION element, so the - selectedIndex - property of the SELECT element
must be changed.

Aah - once again, thanks - i do have one question - what reference
clearly explains and documents the behaviors of the host objects?

thanks again in advance :)
regards,
faisal vali.

<snip useful stuff about patterns for implementing property hooks and
more>
 
R

Richard Cornford

Faisal Vali wrote:
i do have one question - what reference clearly explains
and documents the behaviors of the host objects?

The W3C DOM documentation describes what the specified parts of a
browser object model should do. The browser manufacturer's documentation
(when made available), more or less, explain what their host objects do.
Apart from that it is mostly research through google and trial and error
experimentation.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,816
Latest member
SapanaCarpetStudio

Latest Threads

Top