数组中的高阶函数JS闭包闭包的内存泄漏

Posted 米儿web

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中的高阶函数JS闭包闭包的内存泄漏相关的知识,希望对你有一定的参考价值。

文章根据codewhy老师的课程整理深入JavaScript高级语法-coderwhy大神新课-学习视频教程-腾讯课堂

一、数组中的5个高阶函数

1.filter: 过滤

// [10, 5, 11, 100, 55]
// 10 => false => 不会被放到newNums
// 5 => false => 不会被放到newNums
// 11 => false => 不会被放到newNums
// 100 => false => 不会被放到newNums
// 55 => false => 不会被放到newNums
var newNums = nums.filter(function(item) {
  return item % 2 === 0 // 偶数
})
console.log(newNums)

2.map: 映射

// [10, 5, 11, 100, 55]
var newNums2 = nums.map(function(item) {
  return item * 10
})
console.log(newNums2)

3.forEach: 迭代

nums.forEach(function(item) {
  console.log(item)
})

4. find/findIndex

var item = nums.find(function(item) {
  return item === 11
})
console.log(item)
var friends = [
  {name: "why", age: 18},
  {name: "kobe", age: 40},
  {name: "james", age: 35},
  {name: "curry", age: 30},
]

var findFriend = friends.find(function(item) {
  return item.name === 'james'
})
console.log(findFriend)

var friendIndex = friends.findIndex(function(item) {
  return item.name === 'james'
})
console.log(friendIndex)  打印索引值

5.reduce: 累加

// nums.reduce
// [10, 5, 11, 100, 55]
// var total = 0
// for (var i = 0; i < nums.length; i++) {
//   total += nums[i]
// }
// console.log(total)
// prevValue: 0, item: 10
// prevValue: 10, item: 5
// prevValue: 15, item: 11
var total = nums.reduce(function(prevValue, item) {
  return prevValue + item
}, 0)
console.log(total)

二、JS闭包

JS中函数是一等公民

javascript中,函数是非常重要的,并且是一等公民:

        那么就意味着函数的使用是非常灵活的;

        函数可以作为另外一个函数的参数,也可以作为另外一个函数的返回值来使用;

函数和方法的区别:

// 函数function: 独立的function, 那么称之为是一个函数
function foo() {}
// 方法method: 当我们的一个函数属于某一个对象时, 我们成这个函数是这个对象的方法
var obj = {
  foo: function() {}
}
obj.foo()

JS中闭包的定义

闭包跟函数最大的区别在于,当捕捉闭包的时候,它的 自由变量 会在捕捉时被确定,这样即使脱离了捕捉时的上下文,它也能照常运行;

JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来;

那么我的理解和总结:

        一个普通的函数function,如果它可以访问外层作用域的自由变量,那么这个函数就是一个闭包;

        从广义的角度来说:JavaScript中的函数都是闭包;

         从狭义的角度来说:JavaScript中一个函数,如果访问了外层作用域的变量,那么它是一个闭包;

闭包的访问过程

 闭包的执行过程

那么函数继续执行呢?

 这个时候makeAdder函数执行完毕,正常情况下我们的AO对象会被释放;

 但是因为在0xb00的函数中有作用域引用指向了这个AO对象,所以它不会被释放掉;

  闭包父级作用域不会被销毁,因为还有指针指着父级的OA

闭包的内存泄露

但是目前因为在全局作用域下add10变量对0xb00的函数对象有引用,而0xb00的作用域中AO(0x200)有引用,所以最终会造成这些内存都是无法被释放的;

所以我们经常说的闭包会造成内存泄露,其实就是刚才的引用链中的所有对象都是无法释放的;

那么,怎么解决这个问题呢?

 因为当将add10设置为null时,就不再对函数对象0xb00有引用,那么对应的AO对象0x200也就不可达了;

 在GC的下一次检测中,它们就会被销毁掉;

add10 = null

AO对象不会被销毁时,是否里面的所有属性都不会被释放?

闭包中没引用的会自动被释放

以上是关于数组中的高阶函数JS闭包闭包的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

转《js闭包与内存泄漏》

什么是闭包

js-闭包

JavaScript内存管理闭包和内存泄漏

理解运用JS的闭包高阶函数柯里化

js性能优化之-闭包(内存泄漏)