简体   繁体   中英

Why is this not an infinite loop?

I'm reading this this example and I'm stuck at understanding one line. I need to understand everything so I can't move on.

This function is supposed to hide all the elements inside an object. It's supposed to work. But to me, that for loop looks like an infinite one. Why is it not?

getChild: function (i) {
    return this.children[i];
},

hide: function () {
    for (var node, i = 0; node = this.getChild(i); i++) {
        node.hide();
    }

    this.element.hide(0);
},

From what I see, the function takes the first element of the object with getChild(0) and then calls hide again on that 0-dimension object. Then it resets the counter (i) and gets the first element of the 0-dimension object (which is the same 0-dim object) and calls the function again.

I know I'm mistaken but that's what I see. Please show me the light! Thanks

In a for loop like the one above, the first bit ( var node, i = 0 ) is only executed once, at the beginning of the loop. The loop stops executing when the middle section ( node = this.getChild(i); ) returns false. getChild will return false when there isn't anything at index i . (Technically, it'll return undefined , but that equates to false in this instance).

Secondly, even though hide() is called in the for loop, i is not reset. Why? This recursive call creates a new instance of hide() separate from the original. All of the variables in this new hide() are separate from the original. (and so on, down the rabbit hole).

See http://www.tizag.com/javascriptT/javascriptfor.php for more information on for loops.

The variable i is not reset on each iteration. The only actions that are recurisvely executed are the boolean expression and i++ . node.hide() is not the same as this.hide() . The latter is a different function being called. If it were the same function, then yes, there would be an infinite loop.

The "outer" hide function is being used to "hide" all the elements in this.getChild(i) . node.hide() will call the hide() method on those elements so they are hidden. There is no infinite loop because node.hide() , although it has the same name as the function it's being used in, is not the same function.

  1. The code

    node.hide();

    is still a member of the tree and still traversable. It is just hidden from being displayed.

  2. The initialization part of the for loop

    var node, i=0

    is executed only once, before the looping begins.

  3. The conditional

    node = this.getChild(i)

    evaluates to true (non-null) when there is a child node, and false (null) when it has run out of descendants, thereby breaking out of the loop.

If there is no child at i , getChild will return undefined and break out of the loop.

Consider the following text from the article:

Now create the GalleryImage class. Notice that it uses all of the exact same methods as the GalleryComposite. In other words, they implement the same interface, . Using the same interface is required for the composite to work because a composite element doesn't know whether it's adding another composite element or a leaf, so if it tries to call these methods on its children, it needs to work without any errors.

And consider the constructor for GalleryImage :

var GalleryImage = function (src, id) {
  this.children = [];

  this.element = $('<img />')
  .attr('id', id)
  .attr('src', src);
}

And how the images and composites are constructed:

var container = new GalleryComposite('', 'allgalleries');
var gallery1 = new GalleryComposite('Gallery 1', 'gallery1');
var gallery2 = new GalleryComposite('Gallery 2', 'gallery2');
var image1 = new GalleryImage('image1.jpg', 'img1');
var image2 = new GalleryImage('image2.jpg', 'img2');
var image3 = new GalleryImage('image3.jpg', 'img3');
var image4 = new GalleryImage('image4.jpg', 'img4');

gallery1.add(image1);
gallery1.add(image2);

gallery2.add(image3);
gallery2.add(image4);

container.add(gallery1);
container.add(gallery2);

Since an image cannot contain children, its this.children will remain an empty array. So, when the hide function finally gets called on an image (at one of the leaves of the composite tree), the loop will attempt to evaluate this.children[0] which will return undefined . This will cause the code node = this.getChild(i) to evaluate to a "false" value, and that particular for loop will terminate. Thus preventing an endless loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM