JS 闭包 高阶函数 函数和方法的区别 AO不使用的变量

1. JS函数是一等公民(非常重要)

  • 在js中,函数是非常重要的,并且是一等公民

    • 那么意味着函数的使用是非常灵活的。
    • 函数可以作为另一个函数的参数,也可以作为另一个函数的返回值
  • 自己编写高阶函数

  • 使用内置的高阶函数

1.1 高阶函数

如果一个函数接收另一个函数作为参数时,或这个函数返回另一个函数作为返回值的函数 称之为高阶函数

1.1.1 函数作为参数使用
function calc(num1,num2,calcFn){
  console.log(calcFn(num1,num2));
}
function add(num1,num2){
  return num1+num2;
}
function sub(num1,num2){
  return num1-num2
}
function mul(num1,num2){
  return num1*num2;
}
var m=20;
var n=30;
calc(m,n,add)
calc(m,n,sub)
calc(m,n,mul)
1.1.2 函数作为返回值使用
function makeAdder(count){
  return function add(num){
    return count+num;
  }
}
var add5=makeAdder(5);
var add10=makeAdder(10);
console.log(add5(10));
console.log(add5(50));
console.log(add10(50));

1.2 函数(function)和方法(method)的区别

  • 函数:当一个function是独立的,不属于任何对象的方法时,则称这个function是函数
  • 方法:如果一个function不是独立的,是属于某个对象,则这个function是方法
1.2.1 函数
function foo(){ //foo是一个函数

}
1.2.2 方法
var obj={
  foo:function(){ //这个foo函数是obj的一个方法

  }
}

1.3 数组一些方法的使用

var nums=[10,5,11,100,55]
// 函数function:独立的function,称之为是函数
// methods:方法:当某个function属于某个对象时,我们称这个函数是这个对象的方法

/**
 * * filter
 *  nums.filter((item,index,arr)=>boolean) //这个回调函数会回调5次,因为有5个元素
 * item:值 index:下标 arr:当前这个数组的引用
 */

// * 过滤 返回一个新的数组
var newNums= nums.filter(function(item){
  return item%2===0
})
console.log(newNums);
// * map 映射 [10,5,11,100,55] 返回一个新的数组
var mapNums=nums.map(function(item){
  return item*10
})
console.log(mapNums); //[ 100, 50, 110, 1000, 550 ]

// * forEach 遍历 没有返回值
nums.forEach(function(item){
  console.log(item);
})

// * find(返回数组中元素) findIndex(返回在数组中的索引)
// let a=nums.find(function(item){
//   return item===11
// })
// console.log("a:",a);

var friends=[
  {name:"why",age:18},
  {name:"wjy",age:20},
  {name:"hyz",age:22},
  {name:"tt",age:18},
]
var item=friends.find(function(item){
  return item.name=='wjy'
})
console.log(item); //{ name: 'wjy', age: 20 }

var index=friends.findIndex(function(item){
  return item.name=='hyz'
})
console.log("index:",index); //index: 2


// * reduce 可以对原来的数组进行统计或者累加  nums:[10,5,11,100,55]
// * reduce函数有两个参数,第一个参数是回调函数,第二个参数是回调函数的第一个参数的初始值
// * 回调函数的参数preValue:是上一次回调函返回的值
var total=nums.reduce(function(preValue,item){
  return preValue+item
},0)
console.log(total); //181

2. JS中闭包的定义

闭包的定义,分成两个:在计算机科学中和在JavaScript中

  • 在计算机科学对闭包的定义:(维基百科)

    • 闭包(英语:closure) 又称词法闭包(lexical closure)或函数闭包
    • 是支持在头等函数的编程语言中,实现词法绑定的一种技术
    • 闭包在实现上是一个结构体,它存储了一个函数和一个关联的环境(相当于一个符号查找表)
    • 闭包和函数最大的区别在于,当捕捉闭包的时候,它的自由变量会在捕捉时被确定,这样即使脱离了捕捉时的上下文,它也能照常运行。
  • 闭包的概念出现于60年代,最早实现闭包的程序是Scheme,那么我们就可以理解为什么JavaScript中有闭包

    • 因为js的大量设计是来源于Scheme的
    • 一个函数和对其周围状态(Lexical Enviroment 词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)
    • 也就是说,闭包你可以在一个内层函数中访问到其外层函数的作用域
    • 在js中,每当创建一个函数,闭包就会在函数创建的同时被创建出来
  • codewhy老师的总结

    • 一个普通的函数function,如果它可以访问外层作用域的变量,那么它就是闭包
      • 从广义上来讲,javascript函数都是闭包
      • 从狭义上来讲,javascript中的一个函数,如果访问了外层作用域的变量,那么它就是一个闭包。

2.1 代码示例解析

function foo(){
  var name="foo";
  function bar(){
    console.log(name);
  }
  return bar;
}
var fn=foo();
fn()

// 闭包包括两个部分:  函数+可访问的自由变量
16.png
  • 在这里原本应该销毁的foo的AO对象,但是因为bar函数在引用其name,所以并没有销毁

3. 闭包的内存泄漏

本来该被销毁的对象,却一直没有被销毁,会造成内存泄漏。

  • 从根对象开始,能够被访问的对象不会被销毁
function foo(){
  var name="foo";
  var age=18;
  function bar(){
    console.log(name);
  }
  return bar;
}
let fn=foo()
fn()
17.png
  • 例如上面的AO(0X1002),一直未被销毁,但其实bar()函数只执行了一次,应当被销毁
18.png
  • 因为根对象可到达bar、bar又可到达foo的AO
    • 因为GC采用的是清除标记,只要能从根对象可到达的所有对象不会被销毁,不可到达的对象会被销毁

那怎么解决以上的内存泄漏呢?

其实只要fn调用完后,并设置为null,这样从根对象就不可到达bar了,所以最后bar和foo的AO都被销毁了

4.AO不使用的属性

我们来探究一个问题,就是AO不会被销毁时,是否里面的所有属性都不会被销毁?

下面这段代码中name属于闭包的父级作用域中的变量:

我们知道形成闭包之后age一定不会被销毁,那么name是否被销毁呢?

  • 这里我使用了断点,我们可以在浏览器上查看结果:
19.png

5.总结

闭包.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容