js闭包是怎么产生的
来源:互联网 发布:阿里云服务器防御 编辑:程序博客网 时间:2024/06/10 14:46
首先来看一个实例
这是 HTML代码
<body><button>添加事件</button><input type="button" value="1"><input type="button" value="2"><input type="button" value="3"><input type="button" value="4"><input type="button" value="5"><input type="button" value="6"><input type="button" value="7"></body>
写法一:
<script type="text/javascript">for (var i = document.getElementsByTagName('input').length-1 ; i >= 0; i--) { document.getElementsByTagName('input')[i].onclick = function(){ alert(i); }}</script>
写法二:
<script type="text/javascript">document.getElementsByTagName('button')[0].onclick = function (){for (var i = document.getElementsByTagName('input').length-1 ; i >= 0; i--) {console.log(i); document.getElementsByTagName('input')[i].onclick = function(){ alert(i); }}}</script>
需求 循环给每一个input,绑定一个点击事件,点击不同的input,会产生不同的值。
最后结果是 点击每个input 都是 弹出一样的值。 我们就来解剖一下这2种写法 为什么会产生这样的结果
写法一:
我们知道 在JS中 没有java中 {} 的作用域块,只有函数是独立的作用于块。for循环var 的变量产生的变量没有被函数的作用域块包裹。var 出来的i 暴露在全局环境中,自然而然的挂在了 window对象上。那么打印的 i 等同于 widow.i 。
JS知识点 值传递 和 引用传递 大家先来理解这2句话
1.通过值传递参数在函数体内对变量做修改不会影响变量本身
2.通过对象传递参数在函数体内对变量做更改会影响变量本身
方法一没有被函数包裹吧,那就出于在全局环境中,把全局环境看做一个函数体,window就是函数体对象吧。那么就是第二句话通过对象传递参数会更改变量本身。 只有点击的时候才会触发,所以每次取的i就是取的window上面的i 也就是无论点击那个都是弹出一样的值。
写法二:
我们先谈谈闭包是怎么产生的?官方是这样解释什么是闭包的:
闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
看到这句话就知道闭包与环境有关,与环境有关就离不开作用域。 然而js 作用域中特殊的就是词法作用域
这个词法作用域又称之为静态作用域或者闭包。 词法作用域和闭包或许字面意思难以解释,我们解释静态作用域,静态
作用域,静态的吧。静态作用域就是函数声明时,就已经订好的作用域,以后也不会改变的作用域就是静态作用域。那么为什么
函数声明时就已经订好了作用域呢? js预处理的时候就已经订好了一切。为什么js会预处理呢?因为js这个语言特性就是这样,在
js代码运行时会首先全盘扫描一遍,把该做的都做了。
所以闭包就是这样产生的:
js语言特性在js代码运行的时候就已经把一切都定死了,作用域什么都已经定好了,所以就产生了闭包。
闭包是js语言的一种特性,闭包通常是一个函数,函数是一个独立的作用域,独立的作用域外部环境无法访问,就是闭。封闭自己的词法作用域,
函数有许多特殊形式的函数,这就成就了闭包 包的东西不同,但是它能够引用到的外部函数的成员变量,一定是它包的东西。可以理解为它能够引用外部函数的成员变量,那它就一定是闭包。
写法二的案例就是一个典型的闭包问题,它闭了自己的词法作用域,包了自己的创建环境。js是没有块级作用域,var i 就是外部函数
的成员变量。 然而它包进来的成员变量是一个引用关系,所以最后打印的i也是for循环处理完成的产物。
解决闭包问题的其中的一种方法,用闭包来毁闭包:
<script type="text/javascript">document.getElementsByTagName('button')[0].onclick = function (){for (var i = document.getElementsByTagName('input').length-1 ; i >= 0; i--) {console.log(i); document.getElementsByTagName('input')[i].onclick = function(i){ returnfunction(){ alert(i); };}(i);}}</script>
把外部函数的成员变量当做参数传进去,自执行返回一个独立的词法作用域。取的值的是当时返回的词法作用域已经处理完成的i;与闭包有关的预处理和作用域我博客都有相关的内容,欢迎各位爱好者参观!
阅读全文
1 0
- js闭包是怎么产生的
- 人机对话是怎么产生的?
- 差距是怎么产生的
- JS随机数的产生
- 程序员的性格是怎么产生的?
- 程序员的性格是怎么产生的?
- 程序员的性格是怎么产生的?
- 红酒的色香味怎么产生的
- 太监文学是怎么产生的!
- sysgen环境变量到底怎么产生作用的?
- sysgen环境变量到底怎么产生作用的?
- 怎么解决使用li产生的空隙
- ESC键是怎么产生的?
- 谐振是怎么产生的?什么是谐振?
- 云计算思想是怎么产生的
- AV番号是怎么产生的?
- linux的根目录的是怎么产生的?
- JS产生随机数的几个用法!
- ISIS路由器分类—Level-2 区域间路由
- 数据库——Oracle中创建数据库
- DataNode连接错误Retrying connect to server
- JDBC综合例题
- 神经网络的直观解释
- js闭包是怎么产生的
- c++备忘知识
- 异常捕获
- Java常见集合框架(二十): Map之LinkedHashMap、SortedMap、NavigableMap、TreeMap
- 下拉多选框
- QT5.51 32位VLD找内存泄漏
- 交换机安全——抓包及配置攻击溯源
- js文本框禁止输入表情
- 排序算法