函数及闭包
【摘要】 函数:当函数执行的时候,会形成一个全新的执行上下文(函数体中的代码会在这个上下文中运行),代码运行中,会把所有创建的变量存储到当前上下文的AO(变量对象)中,这些变量是‘私有变量’:除当前上下文中可以使用这些变量的值,上下文以外的环境不能直接使用私有变量的值如果当前上下文中的一些私有信息,则需要函数提供对应的出口,把信息提供给外面使用,而这个出口在js函数中称为returnreturn后面...
函数:当函数执行的时候,会形成一个全新的执行上下文(函数体中的代码会在这个上下文中运行),代码运行中,会把所有创建的变量存储到当前上下文的AO(变量对象)中,这些变量是‘私有变量’:除当前上下文中可以使用这些变量的值,上下文以外的环境不能直接使用私有变量的值
如果当前上下文中的一些私有信息,则需要函数提供对应的出口,把信息提供给外面使用,而这个出口在js函数中称为return
return后面放的一定是值:此处相当于把私有变量的值返回给外面使用
创建一个变量,用来接收函数执行完返回的值:return后面的值
函数名:函数本身
函数名():让函数执行,代表的是函数的返回值
如果函数中没有写return,默认的返回值是undefined
形参:用来存储执行函数时,传递进来的信息,形参是变量
实参:函数执行的时候,传递进来的值会赋值给形参变量=>传递的具体值在JS函数中称为实参,‘实参就是具体传递的值’
形参是创建函数时候设定的变量,实参是执行函数时候给形参传递的具体值
匿名函数:
函数表达式:把一个函数当做值赋值给变量或者事件绑定
document.body.onclick=function(){}
let fn=function(){}
自执行函数:函数创建完就立即执行了
(function(){})()
箭头函数:
let sum=(x,y)=>x+y;
function sum(x,y){
return x+y;
}
两个值的比较:
==左右两边数据类型不一致,先默认转换为一致,在进行比较,隐式转换
Infinity==Infinity =>true 和自己相等,和其他值不相等
NaN和任何值都不相等
null==undefined =>true
null===undefined=>false
对象==对象 比较的是内存地址
对象==字符串 对象转换为字符串
除上述规则外,其余的都是把值转换为数字类型,然后比较
==和===的区别:
1、==进行比较的时候,两边数据类型不一致,则先转换为相同的数据类型,然后再进行比较
2、除了对象==字符串 ,是把对象转换为字符串,其余的都是转换为数组(比较特殊的是对象,对象转为数字,先转字符串,在转数字)
3、===不仅值要相等,数据类型也要相等
闭包:
1、创建函数
开辟一个堆内存
把函数体中的代码当做字符串存储进去
把堆内存的地址赋值给函数名/变量名
函数在哪创建的,那么它执行时候所需要查找的上级作用域就是谁
2、函数执行
形成一个全新的私有作用域、执行上下文、私有栈内存(执行一次形成一个,多个之间也不会产生影响)
形参赋值&变量提升
代码执行(把所属堆内存中的代码字符串一行行执行)
遇到一个变量,首先看它是否为私有变量(形参和在私有作用域中声明的变量是私有变量),是私有的就操作自己的变量即可,不是私有的则向上级作用域查找...一直找到全局作用域为止=>作用域链查找机制
私有变量和外界的变量没有必然关系,可以理解为被私有栈内存保护起来了,这种机制其实就是“闭包的保护机制”
3、关于堆栈内存释放问题
函数执行就会形成栈内存(从内存中分配的一块空间),如果内存都不销毁释放,很容易就会导致栈内存溢出(内存爆满,电脑就卡死了),堆栈内存的释放问题就是学习JS的核心知识之一:
堆内存释放问题:(定时销毁机制 计数销毁机制)
定时销毁机制:浏览器每个一段时间,都会把没有被占用的空间销毁回收
计数销毁机制:浏览器会查看当前空间有几个占用,当占用数量为0时,就销毁这个空间中内容并回收
创建一个引用类型值,就会产生一个堆内存
如果当前创建的堆内存不被其他东西所占用了,(浏览器会在空闲的时候,查找每一个内存的引用状况,不被占用的都会自己给回收释放掉),则会释放
let obj={
name:'zhufeng'
}
let opp=obj;
//此时obj和opp都占用着对象堆内存,想要释放堆内存,需要手动解除变量和值的关联(null:空对象指针)
obj=null;
opp=null;
栈内存释放:
函数执行形成的私有作用域,是否销毁,就看该函数是否返回了一个引用数据类型;
函数若返回的是一个引用数据类型,则这个作用域不会被销毁;反之销毁
打开浏览器形成的全局作用域就是栈内存
手动执行函数形成的私有作用域是栈内存
基于ES6中let/const形成的块作用域也是栈内存
全局栈内存:关掉页面的时候才会销毁
私有栈内存:
1、一般情况下,函数只要执行完成,形成的私有栈内存就会被销毁释放掉(排出出现无限极递归、死循环的模式)
2、但是一旦栈内存中的某个东西(一般都是堆地址)被私有作用域以外的事物给占用了,则当前私有栈内存不能立即被释放销毁(特点:私有作用域中的私有变量等信息也保留下来了)=>市面上认为的闭包:函数执行形成不能被释放的私有栈内存,这样的才是闭包
function fn(){
//....
}
fn();//=>函数执行形成栈内存,执行完成栈内存销毁
function X(){
return function(){
...
}
let f=X();//=>f占用了X执行形成的栈内存的一个东西(返回小函数的堆),则X执行形成的栈内存不能被释放了
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)