javascrpt闭包、变量域的例子:
运行结果:连续输出了10个10。
因为 “i” 这个变量在内存里只保存了一份。
当调用settimeout方法时,往js事件线程的等待队列排入了十个执行函数,一直到每个300ms结束,这十个执行 函数才被调用,此时内存里的 “i” 这个变量经过十次循环最终值已变成了10 。所以就输出了10个10了。
如何输出0-9呢?
可以用闭包把代码改造下:
此时就会输出正确的结果了,为什么?因为在给settimeout传参前,先使用闭包重新生成了一个执行函数,并且把当时循环里的"i"的值作为参 数传入到闭包函数中,结果函数无论什么时候执行,都打出的是当时被传入的那个值。
说明:在给函数传参时,如果传入的参数是位于栈内存上的时候,会将栈 内存值复制一份传入到函数中。
那如果所传参数是个对象,也就是存在于堆内存上时会怎么办。
接着做一个实验,这次的循环对象是一个对象字面量:
输出了什么?还是10个10!为什么?虽然还是使用闭包将当前循环的对象状态作为参数传入执行函数中,但传入的只是栈内存上的变量指针,位于堆内存上的内存仍然只有一份,所以这10个等待任务最终开始执行时,输出的都是同一份内存值。
结论:
1、对于基础数据类型,函数传参的时候会将变量值复制一份传入到函数中。
2、对于对象数据类型,函数传参时是将变量的指针复制一份,真正的变量值只有一份。
由于变量指针和基础类型变量都位于栈内存上,所以传参就是将栈内存复制一遍,堆内存不变。