Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #8254

Re: newbie Javascript checked is null or not an object

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail
Content-Type text/plain; charset="UTF-8"
Message-ID <3002143.SPkdTlGXAF@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Reply-To Thomas 'PointedEars' Lahn <cljs@PointedEars.de>
Organization PointedEars Software (PES)
Date Sat, 12 Nov 2011 13:32:16 +0100
User-Agent KNode/4.4.11
Content-Transfer-Encoding 8Bit
Subject Re: newbie Javascript checked is null or not an object
Newsgroups comp.lang.javascript
References <7a88bf5f-7821-49ca-85a8-bca655c28a36@u9g2000vbx.googlegroups.com> <4ebab172$0$14430$426a34cc@news.free.fr> <4ebb0ac7$0$28592$a8266bb1@newsreader.readnews.com> <1675485.FNyZMGkNft@PointedEars.de>
Followup-To comp.lang.javascript
MIME-Version 1.0
Lines 265
NNTP-Posting-Date 12 Nov 2011 13:32:17 CET
NNTP-Posting-Host c56975e9.newsspool3.arcor-online.net
X-Trace DXC=D^SBP@efGeKlU`@c^jLCbJMcF=Q^Z^V3H4Fo<]lROoRA8kF<OcfhCOKln[0CFce16JDZm8W4\YJNL;?f@h5gMfbLSn@YUKSOd=E:b7jm6OTmfB
X-Complaints-To usenet-abuse@arcor.de
Xref x330-a1.tempe.blueboxinc.net comp.lang.javascript:8254

Followups directed to: comp.lang.javascript

Show key headers only | View raw


Thomas 'PointedEars' Lahn wrote:

> Denis McMahon wrote:
>> var ff=document.form1.elements[elemnum]; // untested
>> 
>> /* then wrap the tests so that it only looks for the checked property on
>> actual checkboxes */
>> 
>> if (ff.type == "checkbox") ff.checked = !ff.checked; // untested
> 
> […]
> However, this code should never be applied to objects that do not have a
> `checked' property in the first place, which renders the question moot and
> the test unnecessary.
> 
>> You could even (and I'm sure someone will shortly post saying why this is
>> bad,
> 
> It is bad,
> 
>> but probably not actually explaining (a) why
> 
> because it is comparably inefficient, incompatible, and unnecessary.

Now as to the why.  Remember, the suggested alternative was (formatted):

  var inputsInListcarsDiv =
    document.getElementById("listcars").getElementsByTagName("input");

  for (var i = 0; i < inputsInListcarsDiv.length; i++)
  {
    if (inputsInListcarsDiv[i].type == "checkbox")
    {
      inputsInListcarsDiv[i].checked = !inputsInListcarsDiv[i].checked;
    }
  }

Efficience
-----------

The suggested alternative is comparably inefficient because it requires a 
lot more property lookups (P), calls (C) and operations (O).  In order of 
execution:

  P: document
  P: document.getElementById
  C: document.getElementById("listcars")
  P: document.getElementById("listcars").getElementsByTagName
  C: document.getElementById("listcars").getElementsByTagName("input");
  P: inputsInListcarsDiv
  O: inputsInListcarsDiv =
       document.getElementById("listcars").getElementsByTagName("input")

  `for' statement:

    P: i
    O: i = 0

    inputsInListcarsDiv.length times (any case):

      P: i
      P: inputsInListcarsDiv
      P: inputsInListcarsDiv.length
      O: ToBoolean(i < inputsInListcarsDiv.length)
      P: inputsInListcarsDiv
      P: inputsInListcarsDiv[i]
      P: inputsInListcarsDiv[i].type
      O: inputsInListcarsDiv[i].type == "checkbox"

    inputsInListcarsDiv.length times (worst case):

      P: inputsInListcarsDiv
      P: inputsInListcarsDiv[i]
      P: inputsInListcarsDiv[i].checked
      O: !inputsInListcarsDiv[i].checked
      P: inputsInListcarsDiv
      P: inputsInListcarsDiv[i]
      P: inputsInListcarsDiv[i].checked
      O: inputsInListcarsDiv[i].checked = !inputsInListcarsDiv[i].checked

    inputsInListcarsDiv.length times (any case):

      P: i
      O: i++

It is a lot more efficient when written as follows:

  var inputsInListcarsDiv =
     document.getElementById("listcars").getElementsByTagName("input");

  for (var i = inputsInListcarsDiv.length; i--;)
  {
    var elem = inputsInListcarsDiv[i];
    if (elem.type == "checkbox")
    {
      elem.checked = !elem.checked;
    }
  }

Then the following property lookups (P), calls (C) and operations (O) would 
take place, in order of execution:

  P: document
  P: document.getElementById
  C: document.getElementById("listcars")
  P: document.getElementById("listcars").getElementsByTagName
  C: document.getElementById("listcars").getElementsByTagName("input")
  P: inputsInListcarsDiv
  O: inputsInListcarsDiv =
       document.getElementById("listcars").getElementsByTagName("input")

  `for' statement:

    P: i
    P: inputsInListcarsDiv
    P: inputsInListcarsDiv.length
    O: i = inputsInListcarsDiv.length

    inputsInListcarsDiv.length times (any case):

      P: i
      O: ToBoolean(i--)
      P: inputsInListcarsDiv
      P: inputsInListcarsDiv[i]
      P: elem
      O: elem = inputsInListcarsDiv[i]
      P: elem.type
      O: elem.type == "checkbox"

    inputsInListcarsDiv.length times (worst case):

      P: elem
      P: elem.checked
      P: elem
      P: elem.checked
      O: !elem.checked
      O: elem.checked = !elem.checked

It is still very inefficient by comparison because it involves

- document.getElementById(), i.e. searching the entire document tree for one
  element (best case), and returning the reference to the corresponding
  element object,

and

- getElementsByTagName(), i.e. searching that element's subtree for
  descendant elements of a certain type (), building a live collection
  containing the corresponding element objects, and returning that
  collection.

The `document.forms' collection, by comparison, is already a live collection 
of objects representing `form' elements, and its `elements' collection is 
already a live collection representing form controls of that particular 
`form' element.  Therefore, the first approach requires only the following, 
in order of execution:

  P: document
  P: document.forms
  P: document.forms["form1"]
  P: document.forms["form1"].elements
  P: elemnum
  P: document.forms["form1"].elements[elemnum]

  [a lot more P's, and O's, and one C]

However, it should be noted that none of those property accesses are 
necessary here.  One can pass `this' from an event handler attribute of a 
control:

  function toggleAll(ctrl, name)
  {
    var checked = ctrl.checked;
    var checkboxes = ctrl.form.elements[name];

    for (var i = checkboxes.length; i--;)
    {
      checkboxes[i].checked = checked;
    }
  }

  <input type="checkbox" … onclick="toggleAll(this, 'foo')">

Which requires the following:

  C: toggleAll(this, 'foo')
  P: checked
  P: ctrl
  P: ctrl.checked
  O: checked = ctrl.checked
  P: ctrl
  P: ctrl.form
  P: ctrl.form.elements
  P: name
  P: ctrl.form.elements[name]
  O: checkboxes = ctrl.form.elements[name]

  `for' statement:

    P: i
    P: checkboxes
    P: checkboxes.length
    O: i = checkboxes.length

    checkboxes.length times:

      P: i
      O: ToBoolean(i--)
      P: checkboxes
      P: i
      P: checkboxes[i]
      P: checked
      O: checkboxes[i] = checked

In any case, one can easily see from this that this kind of element object 
access must be more efficient (and cannot be less standards-compliant or 
less compatible, see below) than the suggested alternative.

Compatibility
--------------

The suggested alternative is comparably incompatible, because not only it 
relies on the availability of the document.getElementById() method, but also 
on that element objects have a getElementsByTagName() method.

The document.getElementById(…) method was introduced with W3C DOM (HTML) 
Level 1 [1].  But in that Specification, the HTMLElement interface has no 
getElementsByTagName() method [2].  It was only introduced there with W3C 
DOM Level 2 Core [3].

By contrast, the `forms' and `elements' collections [4,5] date back to the 
so-called "DOM Level 0" [6] introduced by Netscape Navigator 3.0 [7,8] and 
Internet Explorer 3.0 [9,10].  As a consequence of that, they can be 
expected to be supported by any script-enabled HTML user agent.
 
Unnecessary
------------

Because we already have the `forms' and `elements' live collections in 
either proprietary and standards-compliant implementation, it is not 
necessary to search the entire document tree for suitable elements.

[x] done.

>> or (b) the 'proper' way of doing it)

[x] done.


PointedEars
_________
 [1] <http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-26809268>
 [2] <http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-011100101>
 [3] <http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614>
 [4] <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268>
 [5] <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357>
 [6] <http://www.w3.org/TR/DOM-Level-2-HTML/glossary.html>
 [7] <http://devedge-
temp.mozilla.org/library/manuals/2000/javascript/1.3/reference/document.html>
 [8] <http://devedge-
temp.mozilla.org/library/manuals/2000/javascript/1.3/reference/form.html>
 [9] <http://msdn.microsoft.com/en-us/library/ms531073(VS.85).aspx>
[10] <http://msdn.microsoft.com/en-us/library/ms535249(VS.85).aspx>
-- 
When all you know is jQuery, every problem looks $(olvable).

Back to comp.lang.javascript | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

newbie Javascript checked is null or not an object shall@uaex.edu - 2011-11-09 08:10 -0800
  Re: newbie Javascript checked is null or not an object Elegie <elegie@anonymous.invalid> - 2011-11-09 17:59 +0100
    Re: newbie Javascript checked is null or not an object Denis McMahon <denismfmcmahon@gmail.com> - 2011-11-09 23:20 +0000
      Re: newbie Javascript checked is null or not an object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-10 14:30 +0100
        Re: newbie Javascript checked is null or not an object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-12 13:32 +0100
      Re: newbie Javascript checked is null or not an object shall@uaex.edu - 2011-11-10 05:30 -0800
      Re: newbie Javascript checked is null or not an object David Mark <dmark.cinsoft@gmail.com> - 2011-11-10 06:36 -0800

csiph-web