简体   繁体   English

为什么这不是无限循环?

[英]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. 但对我来说,for循环看起来像是无限的。 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. 从我看到的,该函数使用getChild(0)获取对象的第一个元素,然后再次在该0维对象上调用hide。 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)并获取0维对象的第一个元素(它是相同的0-dim对象)并再次调用该函数。

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. 在如上所述的for循环中,第一个位( var node, i = 0 )仅在循环开始时执行一次。 The loop stops executing when the middle section ( node = this.getChild(i); ) returns false. 当中间部分( node = this.getChild(i); )返回false时,循环停止执行。 getChild will return false when there isn't anything at index i . 当索引i没有任何内容时, getChild将返回false。 (Technically, it'll return undefined , but that equates to false in this instance). (从技术上讲,它将返回undefined ,但在这种情况下等于false )。

Secondly, even though hide() is called in the for loop, i is not reset. 其次,即使在for循环中调用hide()i也不会重置。 Why? 为什么? This recursive call creates a new instance of hide() separate from the original. 这个递归调用创建了一个与原始实例分开的hide()实例。 All of the variables in this new hide() are separate from the original. 这个新的hide()中的所有变量都与原始变量分开。 (and so on, down the rabbit hole). (等等,沿着兔子洞)。

See http://www.tizag.com/javascriptT/javascriptfor.php for more information on for loops. 有关for循环的更多信息,请参见http://www.tizag.com/javascriptT/javascriptfor.php

The variable i is not reset on each iteration. 每次迭代都不会重置变量i The only actions that are recurisvely executed are the boolean expression and i++ . 唯一可以重新执行的操作是布尔表达式和i++ node.hide() is not the same as this.hide() . node.hide()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) . “外部”隐藏功能用于“隐藏” this.getChild(i)所有元素。 node.hide() will call the hide() method on those elements so they are hidden. node.hide()将在这些元素上调用hide()方法,以便隐藏它们。 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. 没有无限循环,因为node.hide()尽管它具有相同的名称,因为它是在正在使用的功能,是一样的功能。

  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 for循环的初始化部分

    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. 当存在子节点时,求值为true(非空),当子节点耗尽时求值为false(null),从而打破循环。

If there is no child at i , getChild will return undefined and break out of the loop. 如果i上没有子getChild ,则getChild将返回undefined并退出循环。

Consider the following text from the article: 请考虑文章中的以下文字:

Now create the GalleryImage class. 现在创建GalleryImage类。 Notice that it uses all of the exact same methods as the GalleryComposite. 请注意,它使用与GalleryComposite完全相同的所有方法。 In other words, they implement the same interface, except that the image is a leaf so it doesn't actually do anything for the methods regarding children, as it cannot have any . 换句话说,它们实现相同的接口, 除了图像是一个叶子,因此它实际上没有为有关子的方法做任何事情,因为它不能有任何 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 : 并考虑GalleryImage的构造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. 由于图像不能包含子图形,因此它的子this.children将保持为空数组。 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 . 因此,当最终在图像上调用hide函数时(在复合树的一个叶子上),循环将尝试评估this.children[0] ,它将返回undefined This will cause the code node = this.getChild(i) to evaluate to a "false" value, and that particular for loop will terminate. 这将导致代码node = this.getChild(i)计算为“false”值,并且特定for循环将终止。 Thus preventing an endless loop. 从而防止无限循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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