Open AwakenedSomeone opened 3 years ago
1.首先简单说一下通常哪些情况会创建作用域,最常见的是函数。除此外:with、try/catch的catch内部也是一个作用域,然后就是直接{...}这种形式的方式,这样直接创建了一个块级作用域。 2.显示的创建块作用域:用{}将一段代码包裹起来,即是显示的创建了一个作用域。 在阅读的时候,了解到,显示创建块作用域的一个好处:影响垃圾回收,这个影响是好的影响,如以下代码: `function process(data) {
// todo something
} var someData = { ... };
process(someData)
var btn = document.getElementById('my_button')
btn.addEventListener('click', function click(evt){
console.log('buton click')
}) ` 这段代码中虽然除了process调用时用到了someData,但在process调用完之后并没有再用到了,应该被回收的,但是因为click函数形成了一个覆盖整个作用域的闭包,js引擎极有可能依然保存着这个结构,someData就得不到释放。如果将
var someData = { ... }; process(someData) ```用花括号包裹起来,则显示的创建了一个作用域,就能让引擎清楚的知,这个someData没有必要保存了 3.let搭配块作用域在for循环里的优势。 如下方的代码:
for (let i = 0; i < 10; i++) { console.log(i) }
for循环头部的let不仅将i绑定到了for循环的块中,事实上它将其重新绑定到了循环的每一个迭代中,确保使用上一个循环迭代结束时的值重新进行赋值。类似于这样的行为:
{
let j; for (j = 0; j < 10; j++) { let i = j; // 每个迭代重新绑定 console.log(i) }
}
这样每一个迭代里都是一个作用域,互不影响,确保使用上一个循环迭代结束时的值重新进行赋值,这样的方式联手闭包,则可以实现一些平时不能实现的东西。比如: 一般写法: ```for (var i = 0; i < 10; i++) { setTimeout(() => { console.log(i) }, i * 1000) }
它会打印出什么?这个经典的例子,大家肯定都知道,会每s打印出1个10,依次答应出10个10,用let加上块作用域和闭包,就能实现我们想要的功能
setTimeout(() => { console.log(i) }, i * 1000) }
原因是块作用域 为每一个迭代都创建了一个i,它等同于这样的写法:
let j = i setTimeout(() => { console.log(j) }, i * 1000) }``` 形成了一个闭包作用域,所以能实现依次答应0 -9的数字出来
1.首先简单说一下通常哪些情况会创建作用域,最常见的是函数。除此外:with、try/catch的catch内部也是一个作用域,然后就是直接{...}这种形式的方式,这样直接创建了一个块级作用域。 2.显示的创建块作用域:用{}将一段代码包裹起来,即是显示的创建了一个作用域。 在阅读的时候,了解到,显示创建块作用域的一个好处:影响垃圾回收,这个影响是好的影响,如以下代码: `function process(data) {
} var someData = { ... };
process(someData)
var btn = document.getElementById('my_button')
btn.addEventListener('click', function click(evt){
console.log('buton click')
}) ` 这段代码中虽然除了process调用时用到了someData,但在process调用完之后并没有再用到了,应该被回收的,但是因为click函数形成了一个覆盖整个作用域的闭包,js引擎极有可能依然保存着这个结构,someData就得不到释放。如果将
for (let i = 0; i < 10; i++) { console.log(i) }
{
}
它会打印出什么?这个经典的例子,大家肯定都知道,会每s打印出1个10,依次答应出10个10,用let加上块作用域和闭包,就能实现我们想要的功能
原因是块作用域 为每一个迭代都创建了一个i,它等同于这样的写法: