JavaScript忍者秘籍笔记02之闭包

若网络条件允许,可以直接看我的个人博客,可能阅读体验更好
点击查看

闭包的作用域

var later;

function outerFunction() {
    var innerValue = true;

    function innerFunction(paramValue) {
        console.log(innerValue); // true
        console.log(paramValue); // true
        console.log(tooLate); // true
    }
    later = innerFunction;
}

outerFunction();

var tooLate = true; // 这个声明必须在later调用前,否则later函数中的tooLate为undefined
later(true);

绑定函数上下文

var button = {
    clicked: false,
    click: function() {
        this.clicked = true;
        console.log(this);
        console.log(button.clicked);
    }
};

var elem = document.getElementById('test');
elem.addEventListener('click', button.click, false);

在本例中,浏览器的事件处理系统认为函数调用的上下文(this)是事件的目标元素,所以才导致其上下文是<button>元素,而不是button对象

// 解决方法1,使用匿名函数
elem.addEventListener('click', function() {
    button.click();
}, false);

// 解决方法2,使用bind方法
elem.addEventListener('click',button.click.bind(button),false);

setTimeout和setInterval也是同样的解决方法,区别是这两个绑定的上下文(this)是window对象

更多请参考:Function.prototype.bind() - JavaScript | MDN

偏应用函数

函数科里化
Function.prototype.curry = function() {
    var fn = this,
        args = Array.prototype.slice.call(arguments); // 将类数组对象arguments转换为数组
    return function() {
        var allArgs = Array.prototype.slice.call(arguments).concat(args);
        return fn.apply(this, allArgs);
    }
}
function add(n1, n2) {
    return n1 + n2;
}

console.log(add.curry(1)(4)); // 5
“分部”函数
Function.prototype.partial = function() {
    var fn = this,
        args = Array.prototype.slice.call(arguments);
    return function() {
        var j = 0;
        for (var i = 0; i < args.length && j < arguments.length; i++) {
            if (args[i] === undefined) {
                args[i] = arguments[j++];
            }
        }
        return fn.apply(this, args);
    };
};

var delay = setTimeout.partial(undefined, 1000);
delay(function() {
    console.log('delay 1 s'); // 1秒后输出
});

使用闭包实现缓存记忆功能

Function.prototype.memoized = function(key) {
    this._values = this._values || {};
    console.log(this);
    return this._values[key] ? this._values[key] : this._values[key] = this.apply(this, arguments);
}

Function.prototype.memoize = function() {
    var fn = this;
    return function() {
        return fn.memoized.apply(fn, arguments);
    }
}

function isPrime(num) {
    var prime = num != 1;
    for (var i = 2; i < num; i++) {
        if (num % i == 0) {
            prime = false;
            break;
        }
    }
    return prime;
}

var isPrimeMemo = isPrime.memoize();

console.log(isPrimeMemo(4)); // false
console.log(isPrimeMemo(7)); // true
console.log(isPrime._values); // { '4': false, '7': true }

即时函数

(…)()中,第一组圆括号仅仅是用于划定表达式的范围,而第二个圆括号则是一个操作符。eg,将函数引用通过圆括号括起来是合法的:

var someFunction = function() {... };
result = (someFunction)();
通过参数限制作用域内的名称
    <img src="../images/ninja-with-pole.png">
    <script type="text/javascript">
    $ = function() {alert('not jQuery!');}; // 定义一个$表示其他内容,而不是jQuery
    (function($) {
        $('img').on('click', function(event) {
            $(event.target).addClass('clickedOn');
        });
    })(jQuery); // 在调用即时函数时,将jQuery作为参数传递进去,就会将jQuery绑定到$参数上了
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值