首页 > 编程语言 >9 JavaScript闭包

9 JavaScript闭包

时间:2023-08-21 15:24:51浏览次数:42  
标签:闭包 小明 函数 JavaScript jiami key js 小芳

9 闭包

我们都知道,函数里是可以访问函数外的全局变量,而函数外不能访问函数内的局部变量,如下:

// 函数外定义a,在函数内可以访问
var a = "测试";
function fn() {
    console.log(a);
}
fn();

执行结果:
image

// 函数内定义a,在函数外访问不到
function fn() {
    var a = "测试";
}
console.log(a);

执行结果:
image

之所以出现这样的情况,就是因为函数内定义的变量为局部变量,函数外定义的变量为全局变量(不同于windows)。在函数内部可以访问到全局变量,而在函数外部是无法访问到函数内部的局部变量的。
接下来,我们先看一段代码:

let name = "水木年华";
function fn() {
    name = "张杰";
}
fn();
console.log(name);	// 张杰

由此可知,在函数内部想要修改外部的变量是十分容易的一件事. 尤其是全局变量. 这是非常危险的. 试想, 我写了一个函数. 要用到name, 结果被别人写的某个函数给修改掉了. 多难受.
接下来,我们来看一个例子:
比如目前有一个项目,需要两个人一起开发,分别是小明.js和小芳.js
小明.js:

var key = '小明的key';
function jiami() {
	console.log("小明使用", key, "来加密");
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小明.js"></script>
    <script>
        fn();   // 小明使用 小明的key 来加密
    </script>
</head>
<body>
</body>
</html>

小芳.js:

var key = '小芳的key';
function jiami() {
	console.log("小芳使用", key, "来加密");
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小芳.js"></script>
    <script>
        fn();   // 小芳使用 小芳的key 来加密
    </script>
</head>
<body>
</body>
</html>

两个人的代码在各自执行的时候都没有问题,但是当把两个js文件同时在一个html文件中引用时,就会出现变量值被修改的问题:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小明.js"></script>
    <script src="小芳.js"></script>
    <script>
	/*两个人都叫jiami,怎样区分调用的是谁的方法?*/
        jiami();
		jiami();
    </script>
</head>
<body>
</body>
</html>

执行结果:
image
很明显,两个脚本在同一个html文件中被引用时,变量名和函数名重复,是不是觉得让各自的变量名和函数名不一致就可以了?如下:
小明.js:

var xiaoming_key = '小明的key';
function xiaoming_jiami() {
	console.log("小明使用", xiaoming_key, "来加密");
}

小芳.js:

var xiaofang_key = '小芳的key';
function xiaofang_jiami() {
	console.log("小芳使用", xiaofang_key, "来加密");
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小明.js"></script>
    <script src="小芳.js"></script>
    <script>
        xiaoming_jiami();
        xiaofang_jiami();
    </script>
</head>
<body>
</body>
</html>

执行结果:
image
这样搞确实可以实现了哈。但是问题来了,这个项目用到的变量和函数少,js脚本也少。而在真正的羡慕中,一个html文件可能引用几十个js文件,每个js文件又有成百上千的变量或者函数,这样的话我在一个一个的去修改变量名和函数名?不太现实,况且在html文件中引用的时候也不方便。那么现在这种情况,我们就可以尝试一下闭包了,比如小明和小芳之前的js代码是在一个函数中的:
小明.js:

function ming() {
	/*
	在外面在套一层函数结构,使key变量和jiami函数的作用范围由之前的全局变为ming函数的局部作用域
	*/
	var key = '小明的key';
	function jiami() {
		console.log("小明使用", key, "来加密");
	}
	return jiami;	// 最后在返回函数名供外部使用
}
ming_jiami = ming();	// 这里的ming_jiami要与小芳的进行区分

小芳.js:

function fang() {
	var key = '小芳的key';
	function jiami() {
		console.log("小芳使用", key, "来加密");
	}
	return jiami;
}
fang_jiami = fang();	// 小芳这里的fang_jiami也要与小明区分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小明.js"></script>
    <script src="小芳.js"></script>
    <script>
        ming_jiami();    // 小明
        fang_jiami();    // 小芳
    </script>
</head>
<body>
</body>
</html>

执行结果:
image
现在执行结果确实没有问题了,两个人的脚本都可以正常使用了。但是两个人外层的函数还是有可能是一样的,我们再用之前学过的匿名函数再优化一下:
小明.js:

ming_jiami = (function(){
	var key = '小明的key';
	function jiami() {
		console.log("小芳使用", key, "来加密");
	}
	return jiami;
})();

小芳.js:

fang_jiami = (function () {
	var key = '小芳的key';
	function jiami() {
		console.log("小芳使用", key, "来加密");
	}
	return jiami;
})();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="小明.js"></script>
    <script src="小芳.js"></script>
    <script>
        ming_jiami();    // 小明
        fang_jiami();    // 小芳
    </script>
</head>
<body>
</body>
</html>

执行结果:
image
OK,至此,就完美的优化了这个代码。在最外面接收内部返回的参数的变量两个人重复的的几率就已经非常低了。何为闭包? 上面这个就是闭包。相信你百度一下就会知道,什么内层函数使用外层函数变量。什么让一个变量常驻内存,等等。其实你细看,它之所以称之为闭包~,它是一个封闭的环境,在内部,自己和自己玩儿,避免了对该模块内部的冲击和改动,避免的变量之间的冲突问题。

闭包的特点:

  • 内层函数对外层函数变量的使用
  • 会让变量常驻与内存

这俩玩意就不解释了,和python的闭包是一个意思。不懂没关系,能看懂他的执行过程就好。

标签:闭包,小明,函数,JavaScript,jiami,key,js,小芳
From: https://www.cnblogs.com/zczhaod/p/17645458.html

相关文章

  • javascript学习笔记day4
    今天重点学习了数组,老实说学过了c#和python的数组,但是今天重新接触js的数字还是有很多要重新学习的,下面是今天的笔记查询条件五个以上时,switch的效果比iflese高两倍以上.letarr=[]声明数组letarr=newArray(1,2,3,4)声明数组修改数组letarr=['a','b','c']for(letinde......
  • JavaScript中的“函数式编程”
    前言我们虽然之前老是听说过“函数式编程”,但一直不能理解,我们静下心来研究了一下,才发现这些东西真的很巧妙。在React这些框架中,对象,函数为王,因为框架已经帮你打建好了在框架中,数据为王,那些函数本身就是用来处理数据这里我们要用更高层的思维,而放弃底层思维,这些本身都是用户数......
  • JavaScript中的数值
    JavaScript中的主要数值类型是Number类型,用于表示整数和近似的实数。JavaScript采用了由IEEE754标准定义的64位浮点格式来表示数值。这意味着JavaScript可以表示最大整数±1.7976931348623157×10^308和最小整数±5×10^-324。JavaScript中的这种数值格式允许我们准确......
  • 8 JavaScript函数
    8JavaScript函数在JS中声明函数和python差不多.也要有一个关键字顶在前面.python是def,到了JS里换成了function,只不过在JS中没有像python那么死板,必须def后面必须跟上函数名.这也为我们未来做逆向提供了第一个超大的伏笔.//语法//声明函数function函数名(形参1,......
  • JavaScript​​-null 、 undefined和布尔值
    null和undefined 概述 null与undefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,老实说,语法效果几乎没区别。vara=undefined;//或者vara=null;上面代码中,变量a分别被赋值为undefined和null,这两种写法的效果几乎等价。在if语句中,它们都会被自......
  • 快速理解什么是 JavaScript 的继承
    其实JavaScript中的继承,就是指的是一种机制,它允许一个对象(子对象)获取另一个对象(父对象)的属性和方法。这样的话子对象可以重用父对象的代码,同时还可以添加自己的特定功能。JavaScript是使用原型继承的方式来实现对象之间的继承关系。首先你肯定得知道一些基本概念:对象:在JavaScrip......
  • JavaScript中的类型、值和变量
    JavaScript的类型可以分为两个主要组别:原始类型和对象类型。JavaScript的原始类型包括数字、文本字符串(简称为字符串)和布尔值(也称为布尔值)。特殊值null和undefined也是原始值,但它们不是数字、字符串或布尔值。这两个值通常被视为各自类型的独特成员。ES6引入了另一种特殊类型,称为......
  • JavaScript性能优化指南:加速前端应用的加载速度
    在当今互联网发展迅猛的时代,用户对于网页加载速度的要求也越来越高。JavaScript是前端开发中不可或缺的一部分,但它也可能成为网页加载变慢的原因之一。本篇文章将带您了解一些JavaScript性能优化的最佳实践,以加速前端应用的加载速度。1.压缩和合并JavaScript文件减少JavaScrip......
  • Python学习 -- 高阶、闭包、回调、偏函数与装饰器探究
    Python函数作为编程的核心,涵盖了众多令人兴奋的概念,如高阶函数、闭包、回调、偏函数和装饰器。本篇博客将深入研究这些概念,结合实际案例为你解析函数的精妙,以及如何巧妙地运用它们来构建更强大、灵活的程序。高阶函数:进一步探索在上文基础上,再次回顾高阶函数,展示它们如何将函数作为......
  • JavaScript
    JS1.js导入方式1.1内部标签<script></script>1.2外部引用a.jsalert("hellojs");<scriptsrc="a.js"></script>2.基本语法<!DOCTYPEhtml><htmllang="en"><head><metacharse......