摘要:引言满满的干货,面试必系列,参考大量资料,并集合自己的理解以及相关的面试题,对核心知识点中的作用域闭包上下文进行了梳理。本篇重点介绍闭包和。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
引言
满满的干货,面试必bei系列,参考大量资料,并集合自己的理解以及相关的面试题,对JS核心知识点中的作用域、闭包、this、上下文进行了梳理。上一篇介绍了作用域和上下文。因为感觉这两个概念互相纠缠,上下文的生成会依赖作用域规则。本篇重点介绍闭包和this。
this先介绍this,因为我觉得this最简单了,掌握住分析的方法,依照方法去分析,毫无难度。
为什么引入this因为我们解耦,为什么要解耦?因为我们要复用!
举个例子:我费了九牛二虎之力写了一个方法,可以对某个数组a进行复杂的操作
var a = [xxx,xxx,....] function foo (){ a xxx // do something to a xxx a // do something to a }
这个方法只能a用 耦合性太强。当其他数组b想用这个方法的时候由于方法里面的操作对象固定是a导致失败。
当然我也不能写成b,因为如果数组c要用难道我们再改成c?
怎么办,显然这个操作的对象不能是固定的,应该说最好是一个变量,谁调用,这个变量就是谁。
this就这么产生了!所以说this的可变是业务的需要,我们要的就是它的可变。当然你要是掌握不了它的变化规则,那么对你来说引入this就是一场灾难了。
总原则: 函数中的this,指的是当前函数的执行主体;谁让函数执行的,那么this就指向谁
在全局作用域下,this指向window;
函数体中的this,看函数执行前有没有".",如果有,那么点前面是谁,this就指向谁;如果没有“.”,那么会指向window;
如果给元素的事件行为绑定方法,那么方法中的this,就会指向当前被绑定的那个元素;
回调函数中的this指向window;
自执行函数中的this永远指向window;
call 、apply、bind可以改变this关键字;
构造函数中的this指向当前类的实例;
改变thisapply call bind可以改变this
问题来了,为什么要改变this?
还记得我之前说的引入this是为了进行更好的复用吗?
js里面没有类,但是通过原型、继承js在努力模仿类。同一个类当然能通过继承复用代码,不同类不继承的情况下怎么复用呢?通过改变this。
举个例子,Array类有reverse方法。只要是数组,都继承了Array的reverse方法,可以直接调用。
[1,2,3].reverse() //[3,2,1]
现在有个类数组arguments,由于不属于Array类,没有办法继承reverse方法,但是我就是想用,咋办?改变this
Array.prototype.reverse.call(argumengts)闭包
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。 wiki
闭包这个东西咋说呢,不同的程序员,不同的资料都有不同的理解。你把它理解为一个函数,也可以把它理解为函数+执行环境。
我们这里不纠结闭包的定义。而是关注闭包的现象,应用,再结合相关面试题去攻克它,最后谈一下我对闭包的思考。
现象话说了一箩筐,你倒是给我上代码呀.....
各位看官息怒,小的再多说几句
之前我们说过了,函数执行,生成执行环境。函数执行完,销毁执行环境。嗯,听上去很正常,不用的东西就销毁嘛。
但是如果函数执行完,该函数上下文还用用怎么办,有用的东西肯定不敢销毁了。这个就是闭包的现象,那么能引起这个现象的鄙人就把它理解为闭包!
function foo () { var a = 1 return function bar () { a++ console.log(a) } } var b = foo() //函数执行完,我就问你foo的上下文你敢销毁吗? b() // 2 b() // 3
大家看foo执行完的结果赋值给了b,也就是函数bar赋值给了b,未来我可能让b执行的,也就是让bar执行,所以我需要保证bar能访问上下文不被销毁。bar能访问的上下文实际上是foo执行时候的上下文。所以foo执行完以后上下文不会被销毁,会继续存在。
我的理解是 函数向外层作用域暴露出了一个内部引用,那么就存在闭包现象(真的没必要纠结闭包到底是啥,是函数?内部整体?是xxx?`。
作用与应用 作用1:保存变量应用: 函数柯里化
var add = (a)=>(b)=> a+b add(2)(3) //5
优点:延迟执行,提前传参,逼格高
应用: 单例模式
//jQ源码 (function(){ var jQuery=function(){ //jq代码 } window.$=window.jQuery=jQuery; //这个通过window对象暴露给外面,根return的暴露是一个意思 })() //函数执行完了,里面的引用暴露给外面了,所以上下文不销毁
优点:变量和函数都写到立即执行函数里面了,避免了污染外层作用域
优缺点闭包无处不在,也许你不经意就写了个闭包。
需要注意的是,由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
总结本篇详细介绍了闭包和this的来源,规律,应用。由于篇幅有限,将在下一篇中会结合各大公司面试题来巩固这些知识,希望给大家带来帮助。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109626.html
摘要:引言满满的干货,面试必系列,参考大量资料,并集合自己的理解以及相关的面试题,对核心知识点中的作用域闭包上下文进行了梳理。如果在小区这个作用域找到了张老师,我就会在张老师的辅导下学钢琴我张老师房间钢琴构成了学琴的上下文环境。 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 满满的干货,面试必bei系列,参考大...
摘要:引言前面两篇文章介绍了上下文作用域闭包。这里我精心挑选了一些特别经典的面试题不定期更新,跪求收藏。闭包组这类题目还是挺简单的,我总结了几个要注意的地方有没有闭包如果有闭包,看创建了几个闭包。不要在脑子里想,每步的结果用纸和笔演算下 showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 前面两篇文章介绍了上下文、作...
摘要:插件开发前端掘金作者原文地址译者插件是为应用添加全局功能的一种强大而且简单的方式。提供了与使用掌控异步前端掘金教你使用在行代码内优雅的实现文件分片断点续传。 Vue.js 插件开发 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins译者:jeneser Vue.js插件是为应用添加全局功能的一种强大而且简单的方式。插....
摘要:好程序员前端培训入门之基础知识梳理汇总,前端工程师是当前各大企业都比较稀缺的人才,薪资待遇和就业前景都很不错。作用域链的前端,始终是当前执行代码所在环境的变量对象。 好程序员Web前端培训入门之JS基础知识梳理汇总,Web前端工程师是当前各大企业都比较稀缺的人才,薪资待遇和就业前景都很不错。不论是专业还是非专业,有基础亦或是无基础,都想通过学习Web前端实现高薪就业。不过,学习要一...
摘要:好程序员前端培训入门之基础知识梳理汇总,前端工程师是当前各大企业都比较稀缺的人才,薪资待遇和就业前景都很不错。作用域链的前端,始终是当前执行代码所在环境的变量对象。 好程序员Web前端培训入门之JS基础知识梳理汇总,Web前端工程师是当前各大企业都比较稀缺的人才,薪资待遇和就业前景都很不错。不论是专业还是非专业,有基础亦或是无基础,都想通过学习Web前端实现高薪就业。不过,学习要一...
阅读 2100·2023-04-25 17:23
阅读 2918·2021-11-17 09:33
阅读 2512·2021-08-21 14:09
阅读 3577·2019-08-30 15:56
阅读 2604·2019-08-30 15:54
阅读 1622·2019-08-30 15:53
阅读 2125·2019-08-29 13:53
阅读 1140·2019-08-29 12:31