简体   繁体   English

混淆在JS中如何使用变量

[英]Confusion with how variables are used in JS

I am new to JS and came across the JS code in which analogy of JS'stop watch object was implemented. 我是JS新手,遇到了JS代码,其中实现了JS秒表对象的类比。 Here is the code: 这是代码:

function Stopwatch() { 
  let startTime, endTime, running, duration = 0;

  this.start = function() {
    if (running) 
      throw new Error('Stopwatch has already started.');

    running = true; 

    startTime = new Date();
  };

  this.stop = function() {
    if (!running) 
      throw new Error('Stopwatch is not started.');

    running = false; 

    endTime = new Date();

    const seconds = (endTime.getTime() - startTime.getTime()) / 1000;
    duration += seconds; 
  };

  this.reset = function() { 
    startTime = null;
    endTime = null;
    running = false; 
    duration = 0; 
  };

  Object.defineProperty(this, 'duration', {
    get: function() { return duration; }
  });
}

I would like to ask some questions on the above code. 我想对上面的代码提出一些问题。 The first question is when we use "running" variable in start method's if statement, does the value of "running" converted from being undefined(by default since it was not given a value) to true? 第一个问题是,当我们在start方法的if语句中使用“ running”变量时,“ running”的值是否从未定义(默认情况下,因为未提供值)转换为true? The second question, after if statement in start method why running was assigned to true. 第二个问题,在启动方法中的if语句之后,为什么运行被分配为true。 The third question, since running was assigned to true in start method Is its value changed globally as well? 第三个问题,因为在start方法中将running分配为true,其值是否也在全局更改? Or globally the value of "running" remains undefined? 还是在全球范围内,“运行”的值仍未定义?

...when we use "running" variable in start method's if statement, does the value of "running" converted from being undefined(by default since it was not given a value) to true? ...当我们在start方法的if语句中使用“运行”变量时,“运行”的值是否从未定义(默认情况下,因为未提供值)转换为true?

undefined is a falsy value: It coerces to false when used as a boolean, as it is in start . undefined是一个伪造的值:用作布尔值时,它强制转换false ,就像在start The falsy values are undefined , null , 0 , NaN , "" , and of course, false . 伪造的值是undefinednull0NaN"" ,当然是false All other values are truthy (including "0" and "false" , which sometimes surprises people). 所有其他值都是真实的 (包括"0""false" ,有时会使人感到惊讶)。

The second question, after if statement in start method why running was assigned to true. 第二个问题,在启动方法中的if语句之后,为什么运行被分配为true。

Because the body of the if (running) statement isn't run, because if (running) is false. 因为if (running)语句的主体未运行,所以if (running)为false。

The third question, since running was assigned to true in start method Is its value changed globally as well? 第三个问题,因为在start方法中将running分配为true,其值是否也在全局更改?

There is only one running variable in the code, which isn't global, but is accessible by all code within the Stopwatch function (even after Stopwatch returns). 代码中只有一个running变量,它不是全局变量,但可以由Stopwatch函数中的所有代码访问(即使在Stopwatch返回之后)。 So setting it true in start means it's then true throughout the code in Stopwatch . 因此,在start将其设置为true意味着在Stopwatch的所有代码中都为true ( stop sets to to false again.) stop再次设置为false 。)

So assume you've just created an instance of Stopwatch . 因此,假设您刚刚创建了Stopwatch的实例。 When you call start : 致电start

  1. if (running) throw... doesn't throw because running is undefined , which is falsy. if (running) throw...throw因为runningundefined ,这是虚假的。
  2. running = true; sets running to true . 设置runningtrue There's only one copy of running (per Stopwatch instance) so all the other code within Stopwatch sees that one variable's current value. 这里只有一个副本running (每Stopwatch实例),从而内的所有其他代码Stopwatch看到的是一个变量的当前值。
  3. startTime = new Date(); saves the start date/time in startTime . 将开始日期/时间保存在startTime Like running , there's only one of these variables (per Stopwatch instance). running一样,这些变量只有一个(每个Stopwatch实例)。

If you then called start again, if (running) throw... would throw , because running is true now. 如果您随后再次调用startif (running) throw...throw ,因为running现在为true

Later, if you call stop : 稍后,如果您致电stop

  1. if (!running) throw... doesn't throw because running is true . if (!running) throw...不会throw因为runningtrue
  2. running = false; sets running to false . 设置runningfalse
  3. endTime = new Date() sets endTime to the current date/time. endTime = new Date()endTime设置为当前日期/时间。
  4. const seconds = (endTime.getTime() - startTime.getTime()) / 1000; determines the time in seconds between when start and stop were called. 确定调用startstop之间的时间(以秒为单位)。
  5. duration += seconds adds seconds to the existing value in duration . duration += secondsduration的现有值增加seconds duration starts out at 0 , but if you do start / stop and then start / stop again, it will record the total duration of both timers. duration0开始,但是如果您先start / stop然后再次start / stop ,它将记录两个计时器的总持续时间。

Javascript variables have lexical scope, so all of the variables defined on line 2 are available throughout function Stopwatch. Javascript变量具有词法范围,因此第2行中定义的所有变量在整个Stopwatch函数中都可用。

Javascript does a lot of type coercion of variables, especially in evaluating conditions. JavaScript会执行很多类型的变量强制,尤其是在评估条件时。 In javascript, the '!' 在javascript中,“!” (not) operator returns a boolean based on how the variable that it's operating on coerces. (不是)运算符根据其对强制变量的操作方式返回布尔值。

When the function starts, running is declared, but not initialized, so javascript initialized it to undefined . 函数启动时,将声明运行,但未初始化,因此javascript将其初始化为undefined undefined coerces to false , so, !undefined === !false === true . undefined强制为false ,所以!undefined === !false === true

In the start function, running is set to true so that future checks of !running will work as expected. 在启动功能中, running设置为true,以便将来对!running检查将按预期进行。

In javascript all the variables are populated with undefined until they are getting a value. 在javascript中,所有变量均使用未定义填充,直到获得值为止。

In your example variables startTime, endTime, running have undefined values when the an instance of Stopwatch is created (they are global in each instance). 在您的示例变量中当创建Stopwatch实例时变量startTime,endTime,runtime具有未定义的值(它们在每个实例中都是全局的)。

start method checks the state of the running variable and then if it has not got the value of true then it updates the value and starts the stopwatch by setting the startTime variable. start方法检查running变量的状态,如果尚未获得true值,则它将更新该值并通过设置startTime变量来启动秒表。

stop method examines the state of running and ensures if it has the proper value (to check if the start method has been called before). stop方法检查running状态并确保其值正确(以检查start方法是否之前已被调用)。 Then, it calculates the duration and sets the value into duration variable. 然后,它计算持续时间并将其值设置为duration变量。

Finally, reset method, simply resets all the values of variables. 最后,使用reset方法,只需重置变量的所有值即可。

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

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