javascript - js中作用域,闭包问题

查看:99
本文介绍了javascript - js中作用域,闭包问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

var data =[];
    for(var i=0;i<3;i++){
        data[i] = function(i){
            console.log(i);
        }
    }
    
    data[0]();
    data[1]();
    data[2]();

1、请问一下为何执行data[0]时是undefined?
2、for循环执行后,会分配3个空间,放着3个function吗?如果是,i的值会传进去吗?
3、执行结果是undefined,是因为执行完for循环完,没有3个空间,都释放了吗?还是其他原因
4、如果像传进去i,要用闭包(我已经试过了),是闭包会分配空间一直不释放吗?有其他方法吗?

解决方案

你这个例子跟闭包没有半毛钱的关系, 你的data数组中只是定义了三个函数,没有调用, 把你的代码改为下面的等价代码, 应该道理就很明显了

var data = []
for(var i=0; i<3; i++){
    data[i] = function (parameter) {
        console.log(parameter)
    }
}

data[0]()// 错误的调用,没有传参数,正确的调用应该是 data[0](argument)
data[1]()
data[2]()

这个例子的原理,发条橙子的作用域链解释得更清楚

如果你想体验闭包的话, 例子应该像下面这样

var data = []
for(var i=0; i<3; i++){
    data[i] = function () {
        console.log(i)
    }
}

data[0]() // 3
data[1]() // 3
data[2]() // 3

如果你想体验IIFE的话, 例子应该像下面这样

var data = []
for(var i=0; i<3; i++){
    data[i] = (function (i) {
            console.log(i)
    }(i));
}

data[0] // 0
data[1] // 1
data[2] // 2

如果你想体验闭包+IIFE的话, 例子应该像下面这样

var data = []
for(var i=0; i<3; i++){
    data[i] = (function (i) {
        return function () {
            console.log(i)
        }
    }(i));
}

data[0]() // 0
data[1]() // 1
data[2]() // 2

因为js中有了作用域链闭包的存在,所以会有上面第一段代码这样的输出,这往往不是开发者所预期和需要的结果,所以在ES5中,大家研究出了IIFE+闭包这种hack式的手法,来解决这个问题,使代码的运行结果更符合预期。

对于防止闭包的误用,ES6引入了块作用域(block)模块(module)箭头函数(arrow function), 可以减少部分对于IIFE+闭包的依赖

参考资料:
闭包: http://speakingjs.com/es5/ch0...
IIFE: http://speakingjs.com/es5/ch1...
IIFE in ES6: http://exploringjs.com/es6/ch...
IIFE in ES6: http://exploringjs.com/es6/ch...

这篇关于javascript - js中作用域,闭包问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆