JS中的作用域以及全局变量的问题
一、 JS中的作用域 |
1、全局变量:函数外声明的变量,称为全部变量
局部变量:函数内部使用var声明的变量,称为局部变量
在JS中,只有函数作用域,没有块级作用域!!!也就是说,if/for等有{}的结构体,并不能具备自己的作用域。
所以,函数外部不能访问函数内部局部变量(私有属性)。因为,函数内部的变量,在函数执行完毕以后,就会被释放掉
2、使用闭包,可以访问函数的私有变量!
JS中,提供了一种“闭包”的概念:在函数内部,定义一个子函数,子函数可以访问父函数的私有便利。可以在子函数中进行操作,最后将子函数通过return返回
function func1(){
var num = 1;
function func2(){
return num;
}
return func2;
} var num = func1()(); console.log(num);
3、闭包的作用:
①可以在函数外部访问函数的私有变量
②让函数内部的变量可以始终存在于内存中,不会再函数调用完成后立即释放。
function func1(){
var num = 1;
function func2(){
return num;
}
return func2;
} var num = func1()(); console.log(num);
结果为1
二、 全局变量的问题 |
【错误原因!!】
代码从上自下,执行完毕后,li的onclick还没有触发,for循环已经转完!
而for循环没有自己的作用域!所以循环5次,用的是同一个全局变量i!也就是在for循环转完后,这个全局变量已经变成了5,那么在怎点li,点第几个都会是5
var lis = document.getElementsByTagName("li");
for(var i=0; i<lis.length;i++){
lis[i].onclick = function(){
alert(i);
}
}
有三种办法解决上述问题:
1、【使用闭包解决上述问题】
解决关键:函数具有自己的作用域!!在for循环转一次,创建一个自执行函数。在美国自执行函数中,都有自己独立的i,而不会被释放掉。
所以for循环转完以后,创建的5个自执行函数的作用域中,分别储存了5个不同的i变量,也就解决了问题
var lis = document.getElementsByTagName("li");
for(var i=0; i<lis.length;i++){
!function(i){
lis[i].onclick = function(){
alert(i);
}
}(i);
}
2、【使用let解决】
解决原理:let具有自己的块级作用域,所以for循环转一次,创建一个块级作用域,思路与闭包相同
var lis = document.getElementsByTagName("li");
for(let i=0; i<lis.length;i++){
lis[i].onclick = function(){
alert(i);
}
}
3、【使用this解决】
解决原理:出错的原则在于全局变量i在多次循环后被污染。那么在点击事件中,就可以不使用i变量,而用this代替lis[i],这样也就不会出现错误!
var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
lis[i].onclick = function(){
console.log(this)
}
}
JS中的作用域以及全局变量的问题的更多相关文章
- 【详解】JS中的作用域、闭包和回收机制
在讲解主要内容之前,我们先来看看JS的解析顺序,我们惯性地觉得JS是从上往下执行的,所以我们要用一个变量来首先声明它,来看下面这段代码: alert(a); var a = 1; 大家觉得这段代码有什 ...
- JS中的作用域及闭包
1.JS中的作用域 在 es6 出现之前JS中只有全局作用域和函数作用域,没有块级作用域,即 JS 在函数体内有自己的作用域,但是如果不是在函数体的话就全部都是全局作用域.比如在 if.for 等有 ...
- 聊一下JS中的作用域scope和闭包closure
聊一下JS中的作用域scope和闭包closure scope和closure是javascript中两个非常关键的概念,前者JS用多了还比较好理解,closure就不一样了.我就被这个概念困扰了很久 ...
- 【授课录屏】JavaScript高级(IIFE、js中的作用域、闭包、回调函数和递归等)、MySQL入门(单表查询和多表联查)、React(hooks、json-server等) 【可以收藏】
一.JavaScript授课视频(适合有JS基础的) 1.IIFE 2.js中的作用域 3.闭包 4.表达式形式函数 5.回调函数和递归 资源地址:链接:https://pan.baidu.com/s ...
- angular.js 中的作用域 数据模型 控制器
1.angular.js 作为后起之秀的前端mvc框架,他于传统的前端框架都不同,我们再也不需要在html中嵌入脚本来操作对象了.它抽象出了数据模型,控制器及视图. 成功解耦了应用逻辑,数据模型,视图 ...
- JS中的作用域和作用域链
本文原链接:https://cloud.tencent.com/developer/article/1403589 前言 作用域(Scope) 1. 什么是作用域 2. 全局作用域和函数作用域 3. ...
- JS中的作用域链
在js中数据的声明方式有两种: 1.用var声明,例如:var num = 10: 2.直接声明,例如:num = 10: 两种声明方式在某些情况下是有区别的: var data = 10; func ...
- 浅析 JS 中的作用域链
作用域链的形成 在 JS 中每个函数都有自己的执行环境,而每个执行环境都有一个与之对应的变量对象.例如: var a = 2 function fn () { var a = 1 console.lo ...
- 谈JS中的作用域链与原型链(1)
学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...
随机推荐
- MPLS VPN随堂笔记2
深入理解ospf 理解MPLS VPN 中对OSPF 层次化设计的补充 supper backbone area 2:理解MPLS VPN 中OSPF 的区域设计概念 3:理解MPLS VPN 中OS ...
- 转:【Java并发编程】之二:线程中断(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17091267 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应 ...
- JS学习五(js中的事件)
[JS中的事件分类] 1.鼠标事件 click/bdlclick/onmouseover/onmouseout 2. HTML事件 onload/onscroll/onsubmit/onchange/ ...
- 201521123061 《Java程序设计》第六周学习总结
201521123061 <Java程序设计>第六周学习总结 ***代码阅读:Child压缩包内 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核 ...
- PTA分享码-Java
主要用于Java语法练习,非竞赛类题目. 1. Java入门 959dbf0b7729daa61d379ec95fb8ddb0 2. Java基本语法 23bd8870e ...
- java web SSO单点登录
第一篇: Web应用系统的演化总是从简单到复杂,从单功能到多功能模块再到多子系统方向发展. .当前的大中型Web互联网应用基本都是多系统组成的应用群,由多个web系统协同为用户提供服务. 多系统应用群 ...
- 本地不安装oracle,plsql照样用起来
对于配置有限的电脑,不安装oracle需要使用plsql怎么设置才可以使用呢 一.首先下载一个instantclient (Oracle提供的一个较为轻量级的客户包) 据说plsql不支持64位的in ...
- org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method test() on null context object
前言 本文中提到的解决方案,源码地址在:springboot-thymeleaf,希望可以帮你解决问题. 至于为什么已经写了一篇文章thymeleaf模板引擎调用java类中的方法,又多此一举的单独整 ...
- MongoDB 分布式架构 复制 分片 适用性范围
转载自 http://www.mongoing.com/archives/3573
- [python学习笔记] 数据类型与语法
数据类型 数值型 int 整形 没有long类型,可以代表任意大小的整数. type(1) -> int float 浮点数 也没有double类型 type(1.2) -> float ...