关于JS中for循环时,作用域问题和this指针指向的总结

 2023-09-05 阅读 386 评论 0

摘要:在大多数计算机语言中,{}这样一对花括弧叫一个块级作用域,也就是一个执行环境。在一个执行环境中,执行环境内部的变量在作用域外部式无法被访问到的。执行环境内部倒是可以访问外部的变量。但由于JS中没有块级作用域,只有函数作用域

在大多数计算机语言中,{}这样一对花括弧叫一个块级作用域,也就是一个执行环境。在一个执行环境中,执行环境内部的变量在作用域外部式无法被访问到的。执行环境内部倒是可以访问外部的变量。
但由于JS中没有块级作用域,只有函数作用域。所以类似于像for(;;){ }这样的作用域,实际上它还是在它的上层作用域之内,如果它上层作用域是global或window,那么实际上这个for循环还是在全局作用域下。

所以,在典型的JS面试题中出现的例子:

const Greeters = []  
for (var i = 0 ; i < 10 ; i++) {  Greeters.push(function () { return console.log(i) })  
}  
Greeters[0]() // 10  
Greeters[1]() // 10  
Greeters[2]() // 10复制代码

由于,此处默认for语句是在全局作用域下,且for循环并不会生成块级作用域,因此,var声明的i变量也就自然在全局作用域之下,在for循环中又出现了一个匿名函数,这个匿名函数倒是有自己的函数作用域。所以,事实上,这个匿名函数先是写好放在那里,还没有被外部声明调用,它就仅仅地待在那里,当外部声明一个Greeters0想要调用这个函数作时,由于i是在全局作用域被var声明出来的,i已经事先被fior语句循环到等于10了,i=10已经事先固定地保存在全局作用域之中不动了。程序再才来调用的这个函数内部的i。这时,函数只需要去全局作用域环境去找到那个事先已经被固定下来的i=10的那个i就行了,所以,无论调用多少次,它只会去调用那个事先已经循环完毕,并被放入全局作用域下i=10那个i。换句话说,for循环语句的那个{}相当于可以视为没有写。

那么如何解决这个问题呢?

又因为JS中var来声明变量时,var声明出来的变量是在当前作用域环境之下, let声明出来的变量也是在当前作用域之下。不一样的是:let可以把类似于这种JS里面不是块级作用域的作用域(例如for(;;){})变成一个块级作用域,而var不会。并且var可以多次声明同一个变量名,而let不行

var a = 5;   
var a = 3;  
let b = 2;   
let b = 4;  
console.console.log(a);  
console.console.log(b); // Identifier 'b' has already been declared复制代码

所以,我们可以用ES6的语法let来创建一个块级作用域。

const Greeters = []  
for (let i = 0 ; i < 10 ; i++) {  Greeters.push(function () { return console.log(i) })  
}  
Greeters[0]() // 0  
Greeters[1]() // 1  
Greeters[2]() // 2复制代码

此时,从外部去调用由于用let每创建一个i,就会去执行一遍内部的匿名函数,并保存起来push进数组Greeters[]里,当你想要调用某一个数组里的函数时,就直接Greetersi 调用对应的数组函数并console.log出当前的i了。

转载于:https://juejin.im/post/59c14d24f265da0672283a75

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/427.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息