js全局变量和局部变量名称一样_JS闭包的理解及常见应用场景

点击上方“ Java资料站 ”,选择“标星公众号”

优质文章,第一时间送达

 范仁义  |  作者

urlify.cn/6fuIVz  |  来源

一、总结(点击显示或隐藏总结内容)

一句话总结:

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

1、如何从外部读取函数内部的变量,为什么?

闭包:f2可以读取f1中的变量,只要把f2作为返回值,就可以在f1外读取f1内部变
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。
function f1(){

2、js链式作用域?

子对象会一级一级向上寻找所有父对象的变量,反之不行。
js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。

3、js变量两种作用域?

全局变量、局部变量(函数内):js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。

4、闭包为什么可以实现在函数外读取到函数内的变量?

|||-begin

function f1(){

|||-end

原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。

回到顶部

二、对JS闭包的理解及常见应用场景

转自或参考:对JS闭包的理解及常见应用场景
https://blog.csdn.net/qq_21132509/article/details/80694517

1、变量作用域

变量作用域两种:全局变量、局部变量。js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。

2、如何从外部读取函数内部的变量?

function f1(){
js链式作用域:子对象会一级一级向上寻找所有父对象的变量,反之不行。
f2可以读取f1中的变量,只要把f2作为返回值,就可以在f1外读取f1内部变量

3、闭包概念

能够读取其他函数内部变量的函数。
或简单理解为定义在一个函数内部的函数,内部函数持有外部函数内变量的引用。

4、闭包用途

1、读取函数内部的变量
2、让这些变量的值始终保持在内存中。不会再f1调用后被自动清除。
3、方便调用上下文的局部变量。利于代码封装。
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。

5、闭包理解

/**
 * [init description]
 * @return {[type]} [description]
 */

6、闭包应用场景之setTimeout

//原生的setTimeout传递的第一个函数不能带参数

7、闭包应用场景之回调

<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>title><link rel="stylesheet" href="">head><style>body{font-size: 12px;
    }h1{font-size: 1.5rem;
    }h2{font-size: 1.2rem;
    }style><body><p>哈哈哈哈哈哈p><h1>hhhhhhhhhh1><h2>qqqqqqqqqh2><a href="#" id="size-12">12a><a href="#" id="size-14">14a><a href="#" id="size-16">16a><script>function changeSize(size){return function(){document.body.style.fontSize = size + 'px';
        };
    }var size12 = changeSize(12);var size14 = changeSize(14);var size16 = changeSize(16);document.getElementById('size-12').onclick = size12;document.getElementById('size-14').onclick = size14;document.getElementById('size-16').onclick = size16;//我们定义行为,然后把它关联到某个用户事件上(点击或者按键)。我们的代码通常会作为一个回调(事件触发时调用的函数)绑定到事件上script>body>html>

8、闭包应用场景之封装变量

<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>闭包模拟私有方法title><link rel="stylesheet" href="">head><body><script>//用闭包定义能访问私有函数和私有变量的公有函数。var counter = (function(){var privateCounter = 0; //私有变量function change(val){
            privateCounter += val;
        }return {increment:function(){ //三个闭包共享一个词法环境
                change(1);
            },decrement:function(){
                change(-1);
            },value:function(){return privateCounter;
            }
        };
    })();console.log(counter.value());//0
    counter.increment();
    counter.increment();//2//共享的环境创建在一个匿名函数体内,立即执行。//环境中有一个局部变量一个局部函数,通过匿名函数返回的对象的三个公共函数访问。script>body>html>

9、闭包应用场景之为节点循环绑定click事件

<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>title><link rel="stylesheet" href="">head><body><p id="info">123p><p>E-mail: <input type="text" id="email" name="email">p><p>Name: <input type="text" id="name" name="name">p><p>Age: <input type="text" id="age" name="age">p><script>function showContent(content){document.getElementById('info').innerHTML = content;
    };function setContent(){var infoArr = [
            {'id':'email','content':'your email address'},
            {'id':'name','content':'your name'},
            {'id':'age','content':'your age'}
        ];for (var i = 0; i < infoArr.length; i++) {var item = infoArr[i];document.getElementById(item.id).onfocus = function(){
                showContent(item.content)
            }
        }
    }
    setContent()//循环中创建了三个闭包,他们使用了相同的词法环境item,item.content是变化的变量//当onfocus执行时,item.content才确定,此时循环已经结束,三个闭包共享的item已经指向数组最后一项。/**
     * 解决方法1 通过函数工厂,则函数为每一个回调都创建一个新的词法环境
     */function showContent(content){document.getElementById('info').innerHTML = content;
    };function callBack(content){return function(){
            showContent(content)
        }
    };function setContent(){var infoArr = [
            {'id':'email','content':'your email address'},
            {'id':'name','content':'your name'},
            {'id':'age','content':'your age'}
        ];for (var i = 0; i < infoArr.length; i++) {var item = infoArr[i];document.getElementById(item.id).onfocus = callBack(item.content)
        }
    }
    setContent()/**
     * 解决方法2 绑定事件放在立即执行函数中
     */function showContent(content){document.getElementById('info').innerHTML = content;
    };function setContent(){var infoArr = [
            {'id':'email','content':'your email address'},
            {'id':'name','content':'your name'},
            {'id':'age','content':'your age'}
        ];for (var i = 0; i < infoArr.length; i++) {
            (function(){var item = infoArr[i];document.getElementById(item.id).onfocus = function(){
                    showContent(item.content)
                }
            })()//放立即执行函数,立即绑定,用每次的值绑定到事件上,而不是循环结束的值
        }
    }
    setContent()/**
     * 解决方案3 用ES6声明,避免声明提前,作用域只在当前块内
     */function showContent(content){document.getElementById('info').innerHTML = content;
    };function setContent(){var infoArr = [
            {'id':'email','content':'your email address'},
            {'id':'name','content':'your name'},
            {'id':'age','content':'your age'}
        ];for (var i = 0; i < infoArr.length; i++) {let item = infoArr[i]; //限制作用域只在当前块内document.getElementById(item.id).onfocus = function(){
                showContent(item.content)
            }
        }
    }
    setContent()script>body>html>

粉丝福利:108本java从入门到大神精选电子书领取

👇👇👇

de00f3306b8a92aab3e6de7ababf491b.png

👆长按上方锋哥微信二维码 2 秒备注「1234」即可获取资料以及可以进入java1234官方微信群

感谢点赞支持下哈 eb28889ee4a4adc43a1eac1e00576bd9.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值