没有合适的资源?快使用搜索试试~ 我知道了~
2.04 面向对象编程.pdf
需积分: 5 0 下载量 56 浏览量
2023-10-27
17:18:19
上传
评论
收藏 615KB PDF 举报
温馨提示
试读
16页
javascript第八课 闭包详解 面向对象编程(OOP) this变化 call和apply
资源推荐
资源详情
资源评论
第4章 面向对象编程
课程介绍
闭包详解
面向对象编程(OOP)
this变化
call和apply
4.1 闭包详解
4.1.1 闭包是什么
在 JavaScript 中,闭包是一个让人很难弄懂的概念。ECMAScript 中给闭包的定义是:闭包,指的是词法表示
包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量。
只是看官方定义的话,并不是很容易理解他的具体意义,我们来分析一下:
闭包是一个函数
闭包可以使用在它外面定义的变量
闭包存在定义该变量的作用域中
好像有点清晰了,但是使用在它外面定义的变量是什么意思,我们先来看看变量作用域。
4.1.2 变量作用域
变量可分为全局变量和局部变量。全局变量的作用域就是全局性的,在 js 的任何地方都可以使用全局变量。在
函数中使用 var 关键字声明变量,这时的变量即是局部变量,它的作用域只在声明该变量的函数内,在函数外面是
访问不到该变量的。
实例:
4.1.3 变量生存周期
<script type="text/javascript">
var city = '广州'; //全局变量
var func = function(){
var company = '前端开发'; //局部变量
console.log(company
); //
前端开发
console.log(city
); //
广州
}
func();
console.log(city); // 广州
console.log(company); // Uncaught ReferenceError: company is not defined
</script>
全局变量,生命周期是永久的。局部变量,当定义该变量的函数调用结束时,该变量就会被垃圾回收机制回收
而销毁。再次调用该函数时又会重新定义了一个新变量。
实例:
a 为局部变量,在 func 调用完之后,a 就会被销毁了。
实例:
可以看出,在第一次调用完 func2 之后,func 中的变量 a 变成 ' hqjy a',而没有被销毁。因为此时 func1 形
成了一个闭包,导致了 a 的生命周期延续了。
这下子闭包就比较明朗了。
闭包是一个函数,比如上面的 func1 函数
闭包使用其他函数定义的变量,使其不被销毁。比如上面 func1 调用了变量 a
闭包存在定义该变量的作用域中,变量 a 存在 func 的作用域中,那么 func1 也必然存在这个作用域中。
现在可以说,满足这三个条件的就是闭包了。
下面我们通过一个简单而又经典的例子来进一步熟悉闭包。
实例:
<script type="text/javascript">
var func = function(){
var a = 'hqjy';
console.log(a);
}
func();
</script>
<script type="text/javascript">
var func = function(){
var a = 'hqjy';
var func1 = function(){
a += ' a';
console.log(a);
}
return func1;
}
var func2 = func();
func2(); // hqjy a
func2(); // hqjy a a
func2(); // hqjy a a a
</script>
我们可能会简单的以为控制台会打印出 0 1 2 3,可事实却打印出了 4 4 4 4,这又是为什么呢?我们发现,
setTimeout 函数是异步的,等到函数执行时,for循环已经结束了,此时的 i 的值为 4,所以 function() {
console.log(i) } 去找变量 i,只能拿到 4。
我们想起上一个例子中,闭包使 a 变量的值被保存起来了,那么这里我们也可以用闭包把 0 1 2 3 保存起来。
实例:
当 i=0 时,把 0 作为参数传进匿名函数中,此时 function(i){} 此匿名函数中的 i 的值为 0,等到 setTimeout
执行时顺着外层去找 i,这时就能拿到 0。如此循环,就能拿到想要的 0 1 2 3。
4.1.4 内存管理
在闭包中调用局部变量,会导致这个局部变量无法及时被销毁,相当于全局变量一样会一直占用着内存。如果
需要回收这些变量占用的内存,可以手动将变量设置为null。
然而在使用闭包的过程中,比较容易形成 JavaScript 对象和 DOM 对象的循环引用,就有可能造成内存泄露。
这是因为浏览器的垃圾回收机制中,如果两个对象之间形成了循环引用,那么它们都无法被回收。
实例:
在上面例子中,func 函数中用匿名函数创建了一个闭包。变量 test 是 JavaScript 对象,引用了 id 为 test 的
DOM 对象,DOM 对象的 onclick 属性又引用了闭包,而闭包又可以调用 test ,因而形成了循环引用,导致两个
对象都无法被回收。要解决这个问题,只需要把循环引用中的变量设为 null 即可。
<script type="text/javascript">
for (var i = 0; i < 4; i++) {
setTimeout(function () {
console.log(i)
}, 0)
}
</script>
<script type="text/javascript">
for (var i = 0; i < 4; i++) {
(function (i) {
setTimeout(function () {
console.log(i)
}, 0)
})(i)
}
</script>
<script type="text/javascript">
function func() {
var test = document.getElementById('test');
test.onclick = function () {
console.log('hello world');
}
}
</script>
剩余15页未读,继续阅读
资源评论
爱因斯坦乐
- 粉丝: 99
- 资源: 23
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 海康威视相机采图交叉编译示例程序,c++
- DETR-基于Tensorflow实现DETR目标检测算法-附流程教程+项目源码-优质项目实战.zip
- 3d激光slam地图发布程序,3d地图点云处理,c++程序
- 送给妈妈的一束鲜花.zip(母亲节祝福HTML源码)
- 稀疏化DETR-基于Pytorch实现稀疏化DETR-SparseDETR-附流程教程+项目源码-优质项目实战.zip
- 人工分类:SLTM的微博评论二分类数据集
- (自适应手机端)响应式房产合同知识产权网站pbootcms模板 企业管理类网站源码下载.zip
- (自适应手机端)响应式动力刀座pbootcms网站模板 五金机械设备类网站源码下载.zip
- 古诗14-南乡子画舸停桡
- 《认识计算机桌面》教案.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功