第3章闭包和高阶函数

第3章闭包和高阶函数

3.1闭包

3.1.1 变量的作用域

3.1.2 变量的生存周期

var Type = {};
for(var i = 0, type; type = ['String','Array','Number'][i++];){
    (function(type){
        Type['is'+type] = function(obj){
            return Object.prototype.toString.call(obj) === '[object '+type+']';
        }
    })(type)
}
var a = Type.isArray([]);//true
var b = Type.isString('str');//true
console.log(a);
console.log(b);

3.1.3 闭包的更多作用

1封装变量

var mult = (function(){
    var cache = {};
    var calculate = function(){
        for(var i = 0, l = arguments.length; i<1; i++){
            a = a*arguments[i];
        }
        return a;
    };
    return function(){
        var args = Array.pototype.join.call(arguments,',');
        if(args in cache){
            return cache[args];
        }
        return cache[args] = calculate.apply(null,arguments);
    }
})()

2延续局部变量的寿命

3.1.4 闭包和面向对象设计

var extent = function(){
    var value = 0;
    return {
        call : function(){
            value++;
            console.log(value);
        }
    }
}

var extent = extent();
extent.call();
extent.call();
extent.call();

//面向对象的写法

var extent = {
    value:0,
    call:function(){
        this.value++;
        console.log(this.value);
    }
}
extent.call();//1
extent.call();//2
extent.call();//3


//或者
var Exent = function(){
    this.value = 0;
}
Exent.prototype.call = function(){
    this.value+;
    console.log(this.value);
}
var extent = new Exent;
extent.call();//1
extent.call();//2
extent.call();//3

3.1.5用闭包实现命令模式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button id="execute">点击我执行命令</button>
<button id="undo">点击我执行命令</button>
    <script>
        var Tv = {
            open:function(){
                console.log("打开电视");
            },
            close:function(){
                console.log("关上电视")
            }
        };
        var OpenTvCommand = function(receiver){
            this.receiver = receiver;
        }
        OpenTvCommand.prototype.execute = function(){
            this.receiver.open();
        }
        OpenTvCommand.prototype.undo = function(receiver){
            this.receiver.close();
        }
        var setCommand = function(command){
            document.getElementById('execute').onclick = function(){
                command.execute();
            }
            document.getElementById('undo').onclick = function(){
                command.undo();
            }
        };
        setCommand(new OpenTvCommand(Tv));
        //把请求封装为对象,从而分离请求的发起者和请求的接收者(执行者)之间的耦合关系

    </script>
</body>
</html>

闭包版本

var Tv = {
    open:function(){
        console.log('打开电视');
    },
    close:function(){
        console.log('关上电视');
    }
};

var createCommand = function(receiver){
    var execute = function(){
        return receiver.open();
    }
    var undo = function(){
        return receiver.close();
    }
    return {
        execute:execute,
        undo:undo
    }
};

var setCommand = function(command){
    document.getElementById('execute').onclick = function(){
        command.execute();
    }
    document.getElementById('undo').onclick = function(){
        command.undo();
    }
};
setCommand(createCommand(Tv));

3.1.3 闭包与内存管理

C++以COM对象的方式实现BOM和DOM COM对象的垃圾收集机制采用的是以引用计数策略

把循环引用中的变量设为null

3.2 高阶函数

3.2.1函数作为参数传递

1回调函数

var appendDiv = function(){
    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.style.display = 'none'
});

2Array.prototype.sort

[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]

3.2.2函数作为返回值输出

1判断数据的类型

var isType = function(type) {
    return function(obj){
        return Object.prototype.toString.call(obj) ==='[object ' + type+']';
    }
}
var isString = isType('Sting');
var isArray = isType('Array');
var isNumber = isType('Number');
console.log(isArray([1,2,3])); //true 

2getSingle

var getSingle = function(fn){
    var ret;
    return function(){
        return ret || (ret = fn.apply(this,arguments))
    }
}

var getSingle = getSingle(function(){
    return document.createElement('script');
})

var script1 = getSingle();
var script2 = getSingle();
console.log(script1===script2); 

3.2.3高阶函数实现AOP

Function.prototype.before = function(beforefn){
    var _self = this;
    return function(){
        beforefn.apply(this,arguments);
        return _self.apply(this,arguments);
    }
}

Function.prototype.after = function(afterfn){
    var _self = this;
    return function(){
        var ret = _self.apply(this,arguments);
        afterfn.apply(this,arguments);
        return ret;
    }
};

var func = function(){
    console.log(2);
}
func = func.before(function(){
    console.log(1);
}).after(function(){
    console.log(3);
});
func();
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容