简体   繁体   English

此 JavaScript 程序中的控制流程

[英]Flow of control in this JavaScript program

Recently I've jumped into JavaScript programming and yesterday I was watching this video about mutability and I got totally confused about the program the host wrote.最近我进入了 JavaScript 编程,昨天我正在观看这个关于可变性的视频,我对主持人编写的程序完全感到困惑。 Here it is:这里是:

 let newObj = { total: 65, increment: 1 }; const IncrementTotal = function(obj, val) { obj.increment = val; return function() { console.log(obj.total); obj.total = obj.total + obj.increment; console.log(obj.total); }; }; const incBy1 = IncrementTotal(newObj, 1); const incBy2 = IncrementTotal(newObj, 2);
 <.DOCTYPE html> <head> <title>JS Test</title> </head> <body> <script src="test1.js"></script> </body> </html>

I've also added the HTML code from my side.我还从我这边添加了 HTML 代码。

When the page is loaded and we call incBy1() in the browser console, the result is当页面加载完毕,我们在浏览器控制台调用incBy1() ,结果是

65

67

At this point I'm unable to follow the host.在这一点上,我无法跟随主机。 He says something like他说类似

by the time incBy1() executes, the value of increment is 2 and both of them point to the same objectincBy1()执行时, increment值为2并且它们都指向同一个 object


What I'm unable to grasp is why is incBy2() called in the first place (we didn't call it)?我无法理解的是为什么首先调用incBy2() (我们没有调用它)? Is it because it's below incBy1() ?是因为它低于incBy1()吗? But then why isn't the data being logged into the console four times ( two times for each )?但是为什么没有四次将数据记录到控制台(每次两次)?

I want to understand how does the program actually execute and why is the output like this.我想了解程序实际上是如何执行的,为什么 output 会这样。

What I'm unable to grasp is why is incBy2() called in the first place (we didn't call it)?我无法理解的是为什么首先调用 incBy2() (我们没有调用它)?

You didn't call incBy2() .您没有致电incBy2() But you did call IncrementTotal by the below line which increases the value of obj.increment :但是您确实通过以下行调用了IncrementTotal ,这增加了obj.increment的值:

const incBy2 = IncrementTotal(newObj, 2);

But then why isn't the data being logged into the console four times (two times for each)?但是为什么没有四次将数据记录到控制台(每次两次)?

That's because you're not invoking incBy2() which would have produced two more console logs.那是因为您没有调用incBy2() ,这会产生另外两个控制台日志。

incBy2 has just been assigned a function returned by IncrementTotal(newObj, 2) . incBy2刚刚被分配了一个由IncrementTotal(newObj, 2)返回的 function 。 Unless you call incBy2() , you won't get this returned function executed.除非您调用incBy2() ,否则您不会执行返回的 function 。 However, as soon as you calls const incBy2 = IncrementTotal(newObj, 2);但是,只要您调用const incBy2 = IncrementTotal(newObj, 2); , IncrementTotal function gets executed and modifies the obj.increment , IncrementTotal function 被执行并修改obj.increment

So this is the flow:所以这是流程:

incBy1 calls IncrementTotal(newObj, 1) which modifies the object property and returns a function to be invoked. incBy1调用IncrementTotal(newObj, 1)来修改 object 属性并返回要调用的 function。 ---Step 1 - -步骤1

Then, incBy2 calls IncrementTotal(newObj, 2) which modifies the object property and returns a function to be invoked.然后, incBy2调用IncrementTotal(newObj, 2)修改 object 属性并返回要调用的 function。 ----Step 2 - - 第2步

Now you just call inc1() which executes the function returned in step 1. When this function gets executed, you see the console log printed twice.现在你只需调用 inc1() 来执行在步骤 1 中返回的 function。当这个 function 被执行时,你会看到控制台日志打印了两次。

Had you invoked inc2() , you could see console.log two more times for a total of 4 times.如果您调用了inc2() ,您可以再看到两次console.log ,总共 4 次。

 let newObj = { total: 65, increment: 1 }; const IncrementTotal = function(obj, val) { obj.increment = val; return function() //let's call it returned function { console.log(obj.total); //l1 obj.total = obj.total + obj.increment; //l2 console.log(obj.total); //l3 }; }; const incBy1 = IncrementTotal(newObj, 1);//this makes obj.increment to 1 const incBy2 = IncrementTotal(newObj, 2);//this makes obj.increment to 2 incBy1() //When this gets called, the `returned function` is executed and it prints `obj.total` which is 65 `(l1)` and then increases obj.total to 65 + 2 (67) `(l2)` and prints it again `(l3)`. //incBy2 <------ had you called this you'd have seen the `returned function` getting executed again printing console.log two more times

The tutorial is about immutability ie how you change the original object.本教程是关于不变性的,即如何更改原始 object。 Here two functions calls are modifying the original object and I'm sure the host wanted to emphasise, by this example, how mutation can produce unwanted side-effects and that you must avoid mutation of original object.这里有两个函数调用正在修改原始 object,我相信主持人想通过这个例子强调突变如何产生不必要的副作用,并且您必须避免原始 object 的突变。 Instead you could create a copy of the object and work on that.相反,您可以创建 object 的副本并进行处理。

Maybe a few cosmetic changes to the code can make it more intuitive for you.也许对代码进行一些外观更改可以使它对您来说更直观。

In this version, I've renamed the functions and the property names, and I've removed the incBy2 variable entirely.在这个版本中,我重命名了函数和属性名称,并且完全删除了incBy2变量。 (See the comments for further clarification.) (有关进一步说明,请参阅评论。)

 // Sets the initial values for the object let newObj = { currentTotal: 65, incrementAmount: "we'll set this later" }; // Defines our main function, which we will call twice const updateIncrementAndMakeNewFunc = function(obj, newIncrement){ // Calling the main function will mutate an object's `incrementAmount` property obj.incrementAmount = newIncrement; // Calling the main function creates this new function, but does NOT call it const newFunc = function(){ console.log(obj.currentTotal); // If this function ever gets called, it will mutate the object's `currentTotal` prop obj.currentTotal = obj.currentTotal + obj.incrementAmount; console.log(obj.currentTotal); }; // The new function will be the output of our main function return newFunc; }; // Calls the main function once // - Sets `newObj.incrementAmount` to `1`, -- Great, but this won't last long // - Returns a function (which is assigned as the value of a new constant) const functionThatWasReturnedFromFirstCall = updateIncrementAndMakeNewFunc(newObj, 1); // Calls the main function a second time // - Sets `newObj.incrementAmount` to `2`, -- THIS IS WHY WE EVENTUALLY SEE `67` // - Returns a function (which is not assigned to anything, so can't be used) updateIncrementAndMakeNewFunc(newObj, 2); // Calls the dynamically created function -- It has never been called till now functionThatWasReturnedFromFirstCall();
 <.DOCTYPE html> <head> <title>JS Test</title> </head> <body> <script src="test1.js"></script> </body> </html>

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

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