js闭包
JS闭包的理解及常见应用场景
打赏
https://www.cnblogs.com/Renyi-Fan/p/11590231.html
> 一、总结(点击显示或隐藏总结内容)
一句话总结:
闭包是指有权访问另一个函数作用域中的变量的函数
1、如何从外部读取函数内部的变量,为什么?
闭包:f2可以读取f1中的变量,只要把f2作为返回值,就可以在f1外读取f1内部变
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。
function f1(){
var n = 123;
function f2(){ //f2是一个闭包
alert(n)
}
return f2;
}
js链式作用域:子对象会一级一级向上寻找所有父对象的变量,反之不行。
2、js链式作用域?
子对象会一级一级向上寻找所有父对象的变量,反之不行。
js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。
3、js变量两种作用域?
全局变量、局部变量(函数内):js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。
4、闭包为什么可以实现在函数外读取到函数内的变量?
|||-begin
function f1(){
var n = 123;
function f2(){ //f2是一个闭包
alert(n)
}
return f2;
}
|||-end
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。
二、对JS闭包的理解及常见应用场景
转自或参考:对JS闭包的理解及常见应用场景
https://blog.csdn.net/qq_21132509/article/details/80694517
1、变量作用域
变量作用域两种:全局变量、局部变量。js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。
2、如何从外部读取函数内部的变量?
function f1(){
var n = 123;
function f2(){ //f2是一个闭包
alert(n)
}
return f2;
}
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]
*/
function init() {
var name = "Chrome"; //创建局部变量name和局部函数alertName
function alertName() { //alertName()是函数内部方法,是一个闭包
alert(name); //使用了外部函数声明的变量,内部函数可以访问外部函数的变量
}
alertName();
}
init();
//一个变量在源码中声明的位置作为它的作用域,同时嵌套的函数可以访问到其外层作用域中声明的变量
/**
* [outFun description]
* @return {[type]} [description]
*/
function outFun(){
var name = "Chrome";
function alertName(){
alert(name);
}
return alertName; //alertName被外部函数作为返回值返回了,返回的是一个闭包
}
var myFun = outFun();
myFun();
/*
闭包有函数+它的词法环境;词法环境指函数创建时可访问的所有变量。
myFun引用了一个闭包,闭包由alertName()和闭包创建时存在的“Chrome”字符串组成。
alertName()持有了name的引用,
myFunc持有了alertName()的的访问,
因此myFunc调用时,name还是处于可以访问的状态。
*/
/**
* [add description]
* @param {[type]} x [description]
*/
function add(x){
return function(y){
return x + y;
};
}
var addFun1 = add(4);
var addFun2 = add(9);
console.log(addFun1(2)); //6
console.log(addFun2(2)); //11
//add接受一个参数x,返回一个函数,它的参数是y,返回x+y
//add是一个函数工厂,传入一个参数,就可以创建一个参数和其他参数求值的函数。
//addFun1和addFun2都是闭包。他们使用相同的函数定义,但词法环境不同,addFun1中x是4,后者是5
6、闭包应用场景之setTimeout
//原生的setTimeout传递的第一个函数不能带参数
setTimeout(function(param){
alert(param)
},1000)
//通过闭包可以实现传参效果
function func(param){
return function(){
alert(param)
}
}
var f1 = func(1);
setTimeout(f1,1000);
7、闭包应用场景之回调
<!DOCTYPE html>
<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>hhhhhhhhh</h1>
<h2>qqqqqqqqq</h2>
<a href="#" id="size-12">12</a>
<a

