1.变量的作用域

前提:这里只全部都通过var创建的变量或对象

1.全局变量:函数外创建变量

  var x=10;
 function test(){
  alert("全局变量在test函数中"+x);
 function a(){
   alert("全局变量在私有函数中"+x); 
 }
  a();

}

2.局部变量:函数内部创建变量。

 

var x=10;
function test(){
  var y=20;
  alert("全局变量在test函数中"+x);//10
  alert("局部变量在test函数中"+y);//20
  alert("局部变量在test函数中"+z);//报错,z未定义
  function a(){
    var z=30;
    alert("局部变量早函数a中"+z);//30
  }
}
注:x书全部变量在整个作用域有效
  y是局部变量在test函数中有效,在a函数外无效
  z是局部变量只在a函数中有效
但是:如果我们想在函数外使用函数的变量怎么办?
这时候就产生了一个东西,闭包。

闭包的概念:是指有权访问另一个函数作用域中的变量的函数。

创建闭包的方式,就是在一个函数内部创建另一个内部(私有)函数。

下面是闭包的实例:

1.

function test(){
  var x=10;
  return function(){
    return x;
  }
}
alert(x);//调用局部变量x,报错未定义
//调用
var a=test();
  alert(a());
说明:a实际上就是闭包匿名函数,函数test中的局部变量x一直保存在内存中,并没有在test调用后被自动清除。

2.

var y;
function test(){
  var x=10;
  y=function(){
    return x;
  }
}
//调用函数
test();//undefined
//调用
alert(y());//10

3.

function test(arg){
  var y=function(){
    return arg;
  }
  arg++;
  return y;
}
var a=test(123);//undefined
alert(a());//124

4.

function test(){
  var x=[];
  var i;
  for(i=0;i<3;i++){
    x[i]=function(){
      return i;
    }
  }
  return x;
}
var a=test();//undefined
alert(a[0]());//3
alert(a[1]());//3
alert(a[2]());//3
说明:输出结果都是3,因为循环完毕i的值为3,三个函数都是指向这一个共同的值,
那么如何解决这个问题呢?下面我们来看。

解决方案一:使用自调函数来实现

function test(){
  var x=[];
  var i;
  for(i=0;i<3;i++){
    x[i]=(function(a){
      return function(){
        return a;
      }
    })(i);
  }
  return x;
}
var a=test();//undefined
alert(a[0]());//0
alert(a[1]());//1
alert(a[2]());//2

方案二:不使用自调函数来实现

function test(){
function makeClosure(x){
    return function(){
      return x;
    }
  }
  var a=[];
  var i;
  for(i=0;i<3;i++){
    a[i]=makeClosure(i);
  }
  return a;
}
var b=test();//undefined
alert(b[0]());//0
alert(b[1]());//1
alert(b[2]());//2

闭包应用实例--Getter与Setter

var getValue,setValue;
(function(){
  var secret=0;
  getValue=function(){
    return secret;
  };
  setValue=function(v){
    secret=v;
  }
})()
alert(getValue())//查看内部变量值
setValue(3)//设置内部局部变量的值
alert(getValue());

  迭代器实例

function setup(x){
  var i=0;
  return function(){
    return x[i++];
  }
}
var next=setup(["a","b","c"]);//undefined
alert(next());//a
alert(next());//b
alert(next());//c

javascript-原生-闭包的更多相关文章

  1. jQuery? 回归JavaScript原生API

    如今技术日新月异,各类框架库也是层次不穷.即便当年漫山红遍的JQuery(让开发者write less, do more,So Perfect!!)如今也有被替代的大势.但JS原生API写法依旧:并且 ...

  2. 深入理解JavaScript的闭包特性如何给循环中的对象添加事件

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  3. 据说每个大牛、小牛都应该有自己的库——JavaScript原生对象拓展

    在据说每个大牛.小牛都应该有自己的库——框架篇中我扬言要做个小牛,没想到一天没更新,小伙儿伴们就戏谑的问我,油哥是不是要太监了?其实事情是这个样子的,这不是太监的节奏,一是,关于写个自己的库的想法由来 ...

  4. JavaScript作用域闭包简述

    JavaScript作用域闭包简述 作用域 技术一般水平有限,有什么错的地方,望大家指正. 作用域就是变量起作用的范围.作用域包括全局作用域,函数作用域以块级作用域,ES6中的let和const可以形 ...

  5. JavaScript的闭包原理

    什么是js(JavaScript)的闭包原理,有什么作用? 一.定义 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 个人的理解是 ...

  6. Js(javaScript)的闭包原理

    问题?什么是js(javaScript)的闭包原理,有什么作用? 一.定义 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.  小编 ...

  7. 深入理解javascript的闭包

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...

  8. JavaScript原生折叠扩展收缩菜单带缓冲动画

    JavaScript原生折叠扩展收缩菜单带缓冲动画 @落雨 <div id="div_two" style="display: none;"> &l ...

  9. 如何给循环中的对象添加事件--深入理解JavaScript的闭包特性

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  10. javascript,jquery(闭包概念)(转)

    偶尔听人说javascript闭包,让我联想起以前学编译原理和数字逻辑里讲的闭包,以前上课讲的闭包很难懂,而且含有递归的意思在里面,现在不想再查看里面的闭包概念. 但javascript我是经常要用, ...

随机推荐

  1. 基于Appium,封装自己的常用方法

    Appium算是老牌移动端App自动化测试工具了,在使用它的过程中,使用者经常会根据个人习惯,把较常用的方法封装在一起,方便调用.以下是我的封装,希望对你有启发. from typing import ...

  2. 从IT圈“鄙视链”看前端开发有多难?

    如今"鄙视链"体现在生活的方方面面,各行各业都有默认一致的鄙视链.IT圈子因为开发语言多样.工程师岗位种类多.技术框架多,也有自己圈子内的鄙视链.按照开发工程师的岗位形成的鄙视链是 ...

  3. noip模拟30

    \(\color{white}{\mathbb{缀以无尽之群星点点,饰以常青之巨木郁郁,可细斟木纹叶脉,独无可极苍穹之览,名之以:密林}}\) 看完题后感觉整套题都没什么思路,而且基本上整场考试确实是 ...

  4. Flask - 访问返回字典的接口报错:The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a dict.

    背景 有一个 Flask 项目,然后有一个路由返回的是 dict 通过浏览器访问,结果报错 关键报错信息 TypeError: 'dict' object is not callable The vi ...

  5. Stream流方法引用

    一.对象存在,方法也存在,双冒号引用 1.方法引用的概念: 使用实例: 1.1先定义i一个函数式接口: 1.2定义一个入参参数列表有函数式接口的方法: 1.3调用这个入参有函数式接口的方法: lamb ...

  6. Mybatis-基本学习(上)

    目录 Mybatis mybatis开始 -----环境准备 一.简介 1.什么是MyBatis 2.持久化 3.持久层 4.为什么需要Mybatis? 二.第一个Mybatis程序 1.搭建环境 1 ...

  7. mybatis关系表

    <select id="selectSingleQuestion" resultType="remarkPaper"> select FrontTi ...

  8. 使用亚马逊服务器报错:Signature not yet current: 20190726T070253Z is still later than 20190726T070246Z (20190726T065746Z + 15 min.)时间不同步的解决办法

    1.首先获取亚马逊的时间: $ curl http://s3.amazonaws.com -v 2.更改当前服务器时间,使之与亚马逊时间同步 $ date -s 'xxxx-xx-xx xx:xx:x ...

  9. 『Python』matplotlib实现动画效果

    一般而言,在绘制复杂动画时,主要借助模块animation来完成 import numpy as np import matplotlib.pyplot as plt import matplotli ...

  10. Java——多线程编程学习/01

    原文章:http://www.cnblogs.com/QG-whz/p/8351298.html  注:建议去看原博主的文章,单就这个知识点而论,比书本讲的透彻,如有违规,联系必删! 并发环境下进行编 ...