翻译:疯狂的技术宅 http://2ality.com/2018/04/extracting-loops.html 在本文中,我们将介绍两种提取循环内数据的方法:内部迭代和外部迭代。...它是 for-of 循环和递归的组合(递归调用在 B 行)。 如果你发现循环内的某些数据(迭代文件)有用,但又不想记录它,那应该怎么办?...内部迭代 提取循环内数据的第一个方法是内部迭代: 1const fs = require('fs'); 2const path = require('path'); 3 4function logFiles...(p)); 这种迭代方式与Array的 .forEach()类似:logFiles() 内实现循环并对每个迭代值(行A)调用 callback。...但我们想要的是在该 iterable 中 yield 每个项目。这就是 yield* 的作用。
什么是JavaScript: JavaScript最初由Netscape的Brendan Eich设计,最初将其脚本语言命名为LiveScript,后来Netscape在与Sun合作之后将其改名为JavaScript...+'\n'+www) 注意:在连接键与字符时用+链接!...var lqj = 26; console.log(window.lqj); for循环中的let与var的不同(let的重要性): 在for循环中使用var来定义一个变量时会出现此变量渗透到循环体外部的问题...(如下:) for (let i = 0;i < 5;i++){ // setTimeout(()=> console.log(i)) } console.log(i) 在for循环中用let...定义一个变量名时,不会出现渗透到循环体以外的情况,如上图所示,循环体以为的操作对循环题内用let定义的i,是无效的!
for (let i of ctaArr) { i.innerHTML = placeholder.cta; } } 分析原因: DOM获取的nodeList...类似数组,但是不是数组,直接用for of循环确实可以遍历,但是在iphone5下回报错,所以需要转为真正的数组。...解决方案: 如上面代码,加了Array.from方法将nodeList转为真实数组之后,iphone5报错消除。
先给出一个知识点,在JS中有些代码是异步执行的,所谓异步,就是不会阻塞代码的运行,而会另外开启一个空间去执行这段异步代码,其余同步的代码就仍正常执行,若异步代码中有其它的代码,则会在之后的某个时刻将异步代码中其它代码执行...multiply(n, n) } function print(n) { let res = calculate(n) console.log(res) } print(5) 当这段代码在浏览器中运行时...在事件循环中涉及到了4个宏队列和2个微队列,如图所示 在了解了基本过程以后,我们先来写一道简单的题 setTimeout(() => { console.log(1); }, 0) setImmediate...假设node开启事件循环需要2毫秒,然后 setTimeout 实际运行的延迟时间是10毫秒,即事件循环开始得比 setTimeout 早,那么在第一轮事件循环运行到 timers 时,发现并没有 setTimeout...阶段是为了处理各种 I/O 事件的,例如文件的读取就属于 I/O 事件,所以我们可以把 setTimeout 和 setImmediate 的代码放在一个文件读取操作的回调内,这样在第一轮循环到达 poll
先给出一个知识点,在JS中有些代码是异步执行的,所谓异步,就是不会阻塞代码的运行,而会另外开启一个空间去执行这段异步代码,其余同步的代码就仍正常执行,若异步代码中有其它的代码,则会在之后的某个时刻将异步代码中其它代码执行...multiply(n, n) } function print(n) { let res = calculate(n) console.log(res) } print(5) 当这段代码在浏览器中运行时...对于11.x 之后的版本,虽然在官网我还没找到相关文字说明是这样的,但通过无数次的运行,暂且可以说是这样的,若各位找到相关的说明,可以留下评论) 同理,Node.js也有宏任务和微任务之分,我们来看一下常用的都有哪些...假设node开启事件循环需要2毫秒,然后 setTimeout 实际运行的延迟时间是10毫秒,即事件循环开始得比 setTimeout 早,那么在第一轮事件循环运行到 timers 时,发现并没有 setTimeout...阶段是为了处理各种 I/O 事件的,例如文件的读取就属于 I/O 事件,所以我们可以把 setTimeout 和 setImmediate 的代码放在一个文件读取操作的回调内,这样在第一轮循环到达 poll
当函数执行完毕,本作用域内的局部变量会销毁。 2.2什么是闭包 闭包(closure)指有权访问另一个函数作用域中变量的函数。简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。...= function() { console.log(i); } })(i); } 闭包应用-循环中的setTimeout() 3秒钟之后,打印所有li元素的内容 for...(var i = 0; i < lis.length; i++) { (function(i) { setTimeout(function() { console.log(lis...[i].innerHTML); }, 3000) })(i); } 闭包应用-计算打车价格 /*需求分析 打车起步价13(3公里内), 之后每多一公里增加 5块钱....total = start + (n - 3) * 5 } return total; }, // 拥堵之后的费用 yd:
而Composition API是基于Vue的响应式系统实现的,与React Hook的相比 声明在setup函数内,一次组件实例化只调用一次setup,而React Hook每次重渲染都需要调用Hook...(err)); 输出结果如下: 0 Error: 0 1 2 3 可以看到在catch捕获到第一个错误之后,后面的代码还不执行,不过不会再被捕获了。...第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。 (2)第二轮时间循环从**setTimeout1**宏任务开始: 首先输出2。...第二轮事件循环结束,第二轮输出2,4,3,5。 (3)第三轮事件循环开始,此时只剩setTimeout2了,执行。 直接输出9。...也就是说,函数fun中参数 n 的值是0,而返回的那个对象中,需要一个参数n,而这个对象的作用域中没有n,它就继续沿着作用域向上一级的作用域中寻找n,最后在函数fun中找到了n,n的值是0。
仔细思考一下就会发现,JavaScript 所谓的事件和触发本质上都通过浏览器中转,更像是浏览器行为而不仅仅是 JavaScript 语言内的一个队列。...setImmediate 的引入是为了解决 setTimeout 的精度问题,由于 setTimeout 指定的延迟时间是毫秒(ms)但实际一次时间循环的时间可能是纳秒级的,所以在一次事件循环的多个外部队列中...接下来,我们再来看一下当 Node.js 在与浏览器端对齐了事件循环的事件之后,这个例子的执行结果为: setImmediate1 promise3 setImmediate2 promise4 setTimeout1...promise1 setTimeout2 promise2 其中主要有两点需要关注,一是外部列队在每次事件循环只执行了一个,另一个是 Node.js 的固定了多个外部队列的优先级。...所以当前外部队列在执行一定数量的 callback 之后会截断。
那么反过来想一想,假如我们在定义了函数之后即刻对其进行了调用,是否此时将会在环境中寻找 i 的值并马上替换掉 console.log(i) 中的 i 呢?...setTimeout是异步任务,并不在主线程上,而是在宏任务队列里,它必须等待主线程的执行栈清空,才有自己的“一席之地”,才能去执行,所以这里我们直接忽略setTimeout,将前三次循环的setTimeout...之后,循环跑完了,主线程的同步任务结束。此时i变成了3。 轮到任务队列了——> 我们回过头调用setTimeout里的回调函数,进行i的输出。...2.利用自执行函数 让函数在定义之后就即刻执行,那么函数中的 i 就会指向当前循环的 i,这个 i 的值为多少在那时就已经确定了,而不再是随着跑循环而动态变化。...这里要理解循环做了什么:每一次循环,实际上执行的是 setTimeout() 方法,执行完之后把每次的回调函数挂载在队列里,后续等主任务清空之后,再一一执行。
从结果来看,for循环执行完跳出之后,才开始执行setTimeout(所以j才等于10),为什么不是每次迭代都执行一次setTimeout呢?...为什么会循环打印十个10 许多人习惯用第二个问题中的执行结果来回答这个问题:for循环执行完跳出之后,才开始执行setTimeout,所以才打印了十个10。...为什么不是每次迭代都执行一次setTimeout 大家都知道,JavaScript在ES6出现以前,是没有块状作用域的,这就意味着, 在for循环中用var定义的变量j,其实是属于全局的,即在全局范围内都可以被访问到...,既然如此,那其实整个全局作用域中就只有一个j,每次for循环都是在更新这个j。...setTimeout的定时,是定时插入执行栈之后立即执行,还是立即插入执行栈定时执行? 期待大家的留言。
2023-07-11:给定正整数 n, 返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。 输入:n = 100。 输出:10。...答案2023-07-11: 函数的主要思路如下: 1.若n小于等于10,则直接返回0,因为在[1, 10]范围内不存在重复数字的情况。 2.计算n的位数和偏移量。...4.3.3.若first在0到9之间,则如果status的第first位为1,说明该数字可用,将offset/10和status的第first位取反异或,并调用递归函数process计算剩余位和可用状态下的数字个数...5.最后的结果为n加1减去noRepeat,即在[1, n]范围内至少有1位重复数字的正整数的个数。...该代码在给定正整数n的范围内采用了一种比较高效的算法,通过一系列的位运算和迭代计算,找出了每个位数下非重复数字的个数,然后根据n的位数和偏移量来计算在该位数下包含至少1位重复数字的正整数的个数,并将它们相加得出最终结果
今天在回顾JavaScript进阶用法的时候,发现一个有趣的问题,话不多说,先上代码: for(var j=0;j<10;j++){ setTimeout(function(){console.log...从结果来看,for循环执行完跳出之后,才开始执行setTimeout(所以j才等于10),为什么不是每次迭代都执行一次setTimeout呢?...为什么会循环打印十个10 许多人习惯用第二个问题中的执行结果来回答这个问题:“for循环执行完跳出之后,才开始执行setTimeout,所以才打印了十个10”。...为什么不是每次迭代都执行一次setTimeout 大家都知道,JavaScript在ES6出现以前,是没有块状作用域的,这就意味着, 在for循环中用var定义的变量j,其实是属于全局的,即在全局范围内都可以被访问到...setTimeout的定时,是定时插入执行栈之后立即执行,还是立即插入执行栈定时执行? 期待大家的留言。
所谓事件循环,就是指处理器在一个程序周期中,处理完这个周期的事件之后,会进入下一个事件周期,处理下一个事件周期的事情,这样一个周期一个周期的循环。...事件循环的阻塞 如果我们在事件处理过程中,某个事件的处理发生了阻塞,则会影响其他的事件的执行,所以我们可以看到在JS中,几乎所有的IO都是非阻塞的。...事件循环举例 我们看一个简单的事件循环的例子: const action2 = () => console.log('action2') const action3 = () => console.log...setImmediate() 和 setTimeout(() => {}, 0)的功能基本上是类似的。它们都会在事件循环的下一个迭代中运行。...我们可以考虑在回调函数内部再次调用setTimeout,这样形成递归的setTimeout调用: const myFunction = () => { console.log('做完后,隔2s再次执行
浏览器执行线程 在解释事件循环之前首先先解释一下浏览器的执行线程: 浏览器是多进程的,浏览器每一个 tab 标签都代表一个独立的进程,其中浏览器渲染进程(浏览器内核)属于浏览器多进程中的一种,主要负责页面渲染...工作线程:也称幕后线程,这个线程可能存在于浏览器或js引擎内,与主线程是分开的,处理文件读取、网络请求等异步事件。...主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。...在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下: 在此次 tick 中选择最先进入队列的任务( oldest task...举例 掌握概念之后,我们来做一个例子强化一下: console.log('script start'); setTimeout(function() { console.log('setTimeout
描述 对于Vue为何采用异步渲染,简单来说就是为了提升性能,因为不采用异步更新,在每次更新数据都会对当前组件进行重新渲染,为了性能考虑,Vue会在本轮数据更新后,再去异步更新视图,举个例子,让我们在一个方法内重复更新一个值...而为了达到这个目的,我们需要将渲染操作推迟到所有的状态都修改完成,为了做到这一点只需要将渲染操作推迟到本轮事件循环的最后或者下一轮事件循环,也就是说,只需要在本轮事件循环的最后,等前面更新状态的语句都执行完之后...,但Vue会在收到信号之后检查队列中是否已经存在这个任务,保证队列中不会有重复,如果队列中不存在则将渲染操作添加到队列中,之后通过异步的方式延迟执行队列中的所有渲染的操作并清空队列,当同一轮事件循环中反复修改状态时...$nextTick方法,Vue中$nextTick方法将回调延迟到下次DOM更新循环之后执行,也就是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,能够获取更新后的DOM。...通过一个简单的例子来演示$nextTick方法的作用,首先需要知道Vue在更新DOM时是异步执行的,也就是说在更新数据时其不会阻塞代码的执行,直到执行栈中代码执行结束之后,才开始执行异步任务队列的代码,
因为Node和操作系统打交道,所以事件循环比较复杂,也有一些自己特有的API。 事件循环在不同的操作系统里有一些细微的差异。这将涉及到操作系统的知识,暂时不表。...但是在node里边有六个队列 到达一个队列后,检查队列内是否有任务(也就是看下是否有回调函数)需要执行。如果有,就依次执行,直到全部执行完毕、清空队列。 如果没有任务,进入下一个队列去检查。...也没有任务回调 在poll队列等待……不断轮询看有没有回调 文件读完,poll队列有了fsFunc回调函数,并且被执行,输出「fs + 时间」 在while死循环那里卡300毫秒, 死循环卡到200ms...check是poll阶段的紧接着的下一个。所以在向下的过程中,先执行check阶段内的回调,也就是先打印setImmediate。...所以起的名字叫Immediate,表示立即的意思。 但是后来问题是,poll里可能有N个任务连续执行,在执行期间想要执行setImmediate是不可能的。因为poll队列不停,流程不向下执行。
先看一个 setTimeout 的例子: // callback function withCallback() { console.log('start') setTimeout(() =>...// callback func 在 setTimeout 被执行后,当过了指定的时间间隔之后,回调函数会被放到队列的末端,再等待事件循环处理到它。...❝注意:也就时因为这种机制,开发者设定给 setTimeout 的时间间隔,并不会精准的等于从执行到触发所经过的时间,使用时要特别注意! ❞ 回调函数虽然在开发中十分常见,但也有许多难以避免的问题。...例如由于函数需要被传递给其他函数,开发者难以掌控其他函数内的处理逻辑;又因为回调函数仅能配合 try … catch 捕捉错误,当异步错误发生时难以控制;另外还有最著名的“回调地狱”。 ?...另外在用循环处理异步事件时,需要注意在 ES6 之后提供的很多 Array 方法都不支持 async/await 语法,如果这里用 forEach 取代 for,结果会变成同步执行,每隔 0.5 秒就打印出数字
(b()); // dev console.log(b) // function(){ return name;} 下面例子 n没有形成闭包,而num形成了闭包(在匿名函数内部去调用了外部函数的变量...(++n); console.log(++num); } } var fn1 = fn(); fn1(); // 1 4 fn1(); // 1 5 2.定时器与闭包 (...因为js是单线程的,在执行for循环的时候定时器被安排到任务队列中排队等待执行,而在等待的过程中,for循环就已经执行了。...等到setTimeout可以执行的时候,for循环已经结束,i的值也已经编程了。...循坏每一次执行都是将值赋值给全局变量 for(var i =0;i<5;i++){ } console.log(i); // 5 let是块级作用域,只能在代码块内起作用。
领取专属 10元无门槛券
手把手带您无忧上云