闭包与函数

170 阅读2分钟

闭包

var name = 'window'
function closure() {
    var name = 'init';
    return {
        get_name: function () {
            return name
        },
        set_name: function (value) {
            name = value;
            return name;
        }
    }
}
var result = closure()
console.log(result.get_name());
result.set_name('syj');
console.log(result.get_name());

答案:init syj

解析:

result.get_name() =>function () {
            return name
        }

因为当前没有name变量,所以往上查找到变量init. result.set_name('syj'); 把name变量的值给改成了syj,所以最后打印syj

引用类型

function lazy_sum(arr) {
    var sum = function () {
        return arr.reduce(function (x, y) {
            return x + y;
        });
    }
    return sum;
}
var f = lazy_sum([1, 2, 3, 4, 5]); 
f(); 
console.log(f());
var f1 = lazy_sum([1, 2, 3, 4, 5]);
var f2 = lazy_sum([1, 2, 3, 4, 5]);
console.log(f1 === f2);
console.log(f1() === f2());

答案:15 false true

解析: reduce数组求和。所以第一个是15, f1 == f2是两个数组进行比较。因为数组是引用数据类型在内存空间里创建的两个地址。所以为false。而f1() =>

arr.reduce(function (x, y) {
    return x + y;
});
内存空间只有一个这个方法。而f1和f2都指向的这个方法。所以f1() === f2()为true

function count() {
    var arr = [];
    for (var i = 1; i <= 3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log( f1());
console.log( f2());
console.log( f3());

答案:16 16 16

解析: 首先执行 var result = count()=>然后去执行for循环,每次循环都创建了一个f函数,把它们添加到arr中 =>arr[f,f,f];三个函数。返回的函数引用了变量i,但它并不是立即执行。等三个函数返回时,再执行=>调用f1(),f2(),f3() 此时i为4了分别打印三个16。f() => return i * i;

如果一定要引用循环变量怎么办?

function count() {
    var arr = [];
    for (var i = 1; i <= 3; i++) {
        arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];

f1(); 
f2(); 
f3(); 
console.log( f1());
console.log( f2());
console.log( f3());

答案:1 4 9

解析:

再创建一个函数,用该函数的参数绑定循环变量当前的值。无论该循环变量后续如何更改。已绑定到函数参数的值不变。