一、 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中的作用域以及全局变量的问题的更多相关文章

  1. 【详解】JS中的作用域、闭包和回收机制

    在讲解主要内容之前,我们先来看看JS的解析顺序,我们惯性地觉得JS是从上往下执行的,所以我们要用一个变量来首先声明它,来看下面这段代码: alert(a); var a = 1; 大家觉得这段代码有什 ...

  2. 聊一下JS中的作用域scope和闭包closure

    聊一下JS中的作用域scope和闭包closure scope和closure是javascript中两个非常关键的概念,前者JS用多了还比较好理解,closure就不一样了.我就被这个概念困扰了很久 ...

  3. angular.js 中的作用域 数据模型 控制器

    1.angular.js 作为后起之秀的前端mvc框架,他于传统的前端框架都不同,我们再也不需要在html中嵌入脚本来操作对象了.它抽象出了数据模型,控制器及视图. 成功解耦了应用逻辑,数据模型,视图 ...

  4. JS中的作用域和作用域链

    本文原链接:https://cloud.tencent.com/developer/article/1403589 前言 作用域(Scope) 1. 什么是作用域 2. 全局作用域和函数作用域 3. ...

  5. JS中的作用域链

    在js中数据的声明方式有两种: 1.用var声明,例如:var num = 10: 2.直接声明,例如:num = 10: 两种声明方式在某些情况下是有区别的: var data = 10; func ...

  6. 谈JS中的作用域链与原型链(1)

    学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助. 先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码 ...

  7. 理解js中的作用域,作用域链以及闭包

    作用域变量作用域的类型:全局变量和局部变量全局作用域对于最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的 <script> var outerVar = " ...

  8. JS中的作用域(一)-详谈

    本篇文章在于详细解读JavaScript的作用域,从底层原理来解释一些常见的问题,例如变量提升.隐式创建变量等问题,在和大家一起交流进步的同时,也算对自己知识掌握的记录,方便以后复习 首先,直接捡干的 ...

  9. JS中最经典的全局变量和局部变量问题

    话不多说,直接上例子: 1.程序的运行结果为:100  10  100 var a = 10; function test(){ a = 100; console.log(a); console.lo ...

随机推荐

  1. 解决clang: error: no such file or directory: such file or directory:的问题

    一,详细问题描述 clang: error: no such file or directory: 'xxx/src/GGBaCollectionViewCell.m' clang: error: n ...

  2. MySQL DBA修炼秘籍

    0.导读 本文主要写给那些立志成为MySQL DBA,以及正在学习MySQL的同行们,结合个人及业内其他同行的职业发展经历给大家一些参考,如何成为合格的MySQL DBA. 1.什么是MySQL DB ...

  3. 【Android Developers Training】 26. 在SQL数据库中保存数据

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. Java Runtime 详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt219 那就首先说点Runtime类吧,他是一个与JVM运行时环境有关的类,这 ...

  5. ReentrantLock源码

    ReentrantLock与Synchronized区别在于后者是JVM实现,前者是JDK实现,属于Java对象,使用的时候必须有明确的加锁(Lock)和解锁(Release)方法,否则可能会造成死锁 ...

  6. 观察者模式与.NET的delegate、event机制

    1.引言 最近在写一些程序玩的时候,接触到了delegate(委托)和event(事件),网上查找了很多的资料,有些博文说可以把delegate近似当做C++当中的函数指针来看,由于自己本身对C++的 ...

  7. 【比赛打分展示双屏管理系统-加强版】的两个ini配置文件功能解释及排行榜滚动界面的简答配置等

    加强版目录下有两个ini文件,功能解释如下: 1. ScoreTip.ini: bScoreTip:如果为1,可以启用 回避 功能 或 高低分差值超出 iScoreRange 的 提示功能. iSco ...

  8. 解决C#调用执行js报检索 COM 类工厂中 CLSID 为 {0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC} 组件失败

    最近做了一个模拟请求的网站简化原网站的繁琐数据,提出有用的数据简单展示并完成post.由于原网站数据有js加密,所以我抓出原网站的js解密方法,由C#调用js得到解密后的数据. 整个抓包的框架是用的苏 ...

  9. Django 框架 Form组件

    一.Form组件简介 Form组件是django中一个非常强大的组件,在处理服务端和前端的交互上大大的提高了开发人员的开发速度. Form组件的功能: 用于处理前后端的数据认证(显示错误信息) 用于生 ...

  10. Re:从零开始的Spring Session(三)

    上一篇文章中,我们使用Redis集成了Spring Session.大多数的配置都是Spring Boot帮我们自动配置的,这一节我们介绍一点Spring Session较为高级的特性. 集成Spri ...