【第三章】闭包和高阶函数

闭包作用

封装变量

把不需要暴露在全局的变量封装成 “私有变量”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//计算乘积一般方法
var mult = function(){
var a = 1
for(var i=0;l=arguments.length;i<l;i++){
a *= arguments[i]
}
return a
}
/*
对于相同的参数来说,每次进行计算是一种浪费
所以可以加入缓存机制来提高这个函数的性能
*/
var cache = {}
var mult = function () {
var args = Array.prototype.join.call(arguments, ',')
//args = '1,2,3' 类数组使用join方法
if (cache[args]) {
return cache[args]+'[]'
}
var a = 1
var l = arguments.length;
for (var i = 0; i < l; i++) {
a *= arguments[i]
}
return cache[args] = a
// cache = { '1,2,3': 6 ,...}
}
console.log(mult(1,2,3)) // 6
console.log(mult(1,2,3)) // 6[] 不进行再次循环 直接取cache内存的值
console.log(mult(1,2,5)) // 10
console.log(cache) // { '1,2,3': 6 ,'1,2,5': 10}
/*
虽然 cache 只在mult函数中使用
但是 被放在了全局变量中 不能被释放
实现在mult中
通过闭包的方式实现 */
var mult = (function(){
var cache = {}
return function(){
var args = Array.prototype.join.call(arguments, ',')
if (cache[args]) {
return cache[args]+'[]'
}
var a = 1
var l = arguments.length;
for (var i = 0; i < l; i++) {
a *= arguments[i]
}
return cache[args] = a
}
})()
//提炼函数
var mult = (function(){
var cache = {}
var calculate = function(){
var a = 1
for(var i=0,l=arguments.length;i<l;i++){
a *= arguments[i]
}
return a
}

return function(){
var args = Array.prototype.join.call(arguments,',')
if( args in cache ){
return cache[args]
}
return cache[args] = calculate.apply(null,arguments)
//用apply主要是因为arguments是一个数组 更方便传参 不需要处理类型
//es6也可以直接用 calculate(...arguments)
}
})()

延长局部变量的寿命

变量一直处于被引用状态 所以不会释放缓存?

高阶函数

需要满足的条件

  1. 函数可以作为参数被传递
  2. 函数可以作为返回值输出

函数作为参数传递

  1. 回调函数

    回调函数的应用不仅只在异步请求中,当一个函数不适合执行一些请求时,我们也可以把这些请求封装成一个函数,并把它作为参数传递给另外一个函数,“委托”给另外一个函数来执行。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var appendDiv = function (callback) {
    for (var i = 0; i < 100; i++) {
    var div = document.createElement('div');
    div.innerHTML = i;
    document.body.appendChild(div);
    if (typeof callback === 'function') {
    callback(div);
    }
    }
    };
    appendDiv(function (node) {
    node.style.display = 'none'
    })
    1. Array.prototype.sort
      Array.prototype.sort 接受一个函数当作参数,这个函数里面封装了数组元素的排序规则。从Array.prototype.sort 的使用可以看到,我们的目的是对数组进行排序,这是不变的部分;而使用什么规则去排序,则是可变的部分。把可变的部分封装在函数参数里,动态传入Array.prototype.sort,使 Array.prototype.sort 方法成为了一个非常灵活的方法,代码如下
      1
      2
      3
      4
      5
      6
      7
      8
      9
      //从小到大排列
      [ 1, 4, 3 ].sort( function( a, b ){
      return a - b;
      }) // [1,3,4]

      //从大到小排序
      [ 1, 4, 3 ].sort( function( a, b ){
      return b - a;
      }) // [4,3,1]

    函数作为返回值输出

  2. 判断数据的类型

    通过 Object.prototype.toString.call(obj) 判断数据类型(最好的方法)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var isType = function(type){
    return function(obj){
    return Object.prototype.toString.call(obj) == '[object '+type+']'
    }
    }

    isType('String')('a') //true
    isType('Array')([1,2]]) //true

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2019-2023 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信