新人学习闭包时碰到的问题

weixin_41917520 2018-10-05 04:48:31
新人,刚刚在学习js。
刚刚自己写了一段代码
<script type="application/javascript">
function a()
{
var c=1;
var d=5;
b();
function b()
{
a=function()
{return d;}
}
return [c,b];
}
alert(a()[0]);
alert(a());
</script>
系统分别显示1,5。到这里很正常,我基本可以理解。但是我把代码稍稍改了一下之后就发生了一些我不大能理解的变化了。
第一次改动
<script type="application/javascript">
c=function b()
{
function a()
{
b=function b()
{return 2;}
}
a();
return 1;
}

alert(c());
alert(c());
</script>
只是将function b赋值给了变量C,return的值就都是1了,请问为什么?
第二次改动
<script type='text/javascript'>
function a()
{
var c=1;
var d=2;

function b()
{return c;}

function f()
{
b=function ()
{return d; }
}

var e=[b,f];
return e;
}

var b=a()[0];
var f=a()[1];
alert(b());
f();
alert(b())
</script>

这次我改动的对象不再是函数本身,而是函数内部的函数。为什么两次的值都是1?

...全文
122 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_41917520 2018-10-11
  • 打赏
  • 举报
回复
引用 6 楼 jslang 的回复:
你的帖子标题是“学习闭包时碰到的问题”。 这种现象就是闭包的特性啊。 闭包是指创建的函数会与创建函数所在的作用域绑定在一起。只要这个函数存在,创建函数所在的作用域和作用域中的变量就一直存在,不会被系统回收。可以让函数内始终能访问作用域中的变量。
我想再问一下,对于第一段代码。 在我用 a=function() {return d;} 改写了a函数的时候,系统里发生的实际情况到底是什么?我之前的理解是a函数被覆盖掉了,但现在觉得是不是我只是创建了一个新的函数并且把a这个名字从旧函数那边放到了新函数头上。旧函数虽然失去了名字但是依然存在,并且默默地在为其他子函数继续提供着那些变量?
天际的海浪 2018-10-11
  • 打赏
  • 举报
回复
引用 7 楼 weixin_41917520 的回复:
[quote=引用 6 楼 jslang 的回复:] 你的帖子标题是“学习闭包时碰到的问题”。 这种现象就是闭包的特性啊。 闭包是指创建的函数会与创建函数所在的作用域绑定在一起。只要这个函数存在,创建函数所在的作用域和作用域中的变量就一直存在,不会被系统回收。可以让函数内始终能访问作用域中的变量。
我想再问一下,对于第一段代码。 在我用 a=function() {return d;} 改写了a函数的时候,系统里发生的实际情况到底是什么?我之前的理解是a函数被覆盖掉了,但现在觉得是不是我只是创建了一个新的函数并且把a这个名字从旧函数那边放到了新函数头上。旧函数虽然失去了名字但是依然存在,并且默默地在为其他子函数继续提供着那些变量?[/quote] 旧函数是没有被系统回收,但不完全是你理解的那样。 旧a函数执行时会先创建一个局部作用域,之后在函数内声明的局部变量都会放到这个局部作用域中。函数相当于工具,局部作用域则是由函数这个工具生产的成品。 “闭包”所保留的是局部作用域这个成品,不是函数本身。 旧函数之所以没有被系统回收,是因为在局部作用域中有对旧函数的引用,可以在这个局部作用域中用arguments.callee访问旧函数。
天际的海浪 2018-10-08
  • 打赏
  • 举报
回复
你的帖子标题是“学习闭包时碰到的问题”。 这种现象就是闭包的特性啊。 闭包是指创建的函数会与创建函数所在的作用域绑定在一起。只要这个函数存在,创建函数所在的作用域和作用域中的变量就一直存在,不会被系统回收。可以让函数内始终能访问作用域中的变量。
weixin_41917520 2018-10-07
  • 打赏
  • 举报
回复
引用 3 楼 jslang 的回复:
js中函数或对象都是按引用地址传递的。 你一开始c和b中存放的是同一个函数的引用地址。当对b重新赋值了一个新函数。b中存放的就变成新函数的引用地址,这就与原来的函数断开了联系。但是c存放的还是原来函数的引用地址。 你第二次改动的代码也是同样道理。一开始a函数中的b与全局作用域中的b中存放的是同一个函数的引用地址。 当在f函数内对a函数内的b重新赋值。a函数内的b中存放的就变成新函数的引用地址,但是全局作用域中的b存放的还是原来函数的引用地址。 。
想再问一下,对于最初的那个代码,既然在第一次运行function b后,function a已经重写成了 a=function() {return d;} var d是属于之前的function a的局部变量,而这个新的function a里是不含有var d的。所以新function a又是为什么能访问到之前function a的var d的值的?还是说新的function a即使什么都不写也是默认继承之前旧function a的所有变量的?
weixin_41917520 2018-10-05
  • 打赏
  • 举报
回复
引用 3 楼 jslang 的回复:
js中函数或对象都是按引用地址传递的。 你一开始c和b中存放的是同一个函数的引用地址。当对b重新赋值了一个新函数。b中存放的就变成新函数的引用地址,这就与原来的函数断开了联系。但是c存放的还是原来函数的引用地址。 你第二次改动的代码也是同样道理。一开始a函数中的b与全局作用域中的b中存放的是同一个函数的引用地址。 当在f函数内对a函数内的b重新赋值。a函数内的b中存放的就变成新函数的引用地址,但是全局作用域中的b存放的还是原来函数的引用地址。 。
完全明白了,谢谢了
天际的海浪 2018-10-05
  • 打赏
  • 举报
回复
js中函数或对象都是按引用地址传递的。 你一开始c和b中存放的是同一个函数的引用地址。当对b重新赋值了一个新函数。b中存放的就变成新函数的引用地址,这就与原来的函数断开了联系。但是c存放的还是原来函数的引用地址。 你第二次改动的代码也是同样道理。一开始a函数中的b与全局作用域中的b中存放的是同一个函数的引用地址。 当在f函数内对a函数内的b重新赋值。a函数内的b中存放的就变成新函数的引用地址,但是全局作用域中的b存放的还是原来函数的引用地址。 。
weixin_41917520 2018-10-05
  • 打赏
  • 举报
回复
引用 1 楼 jslang 的回复:
你原本的代码是在第一次调用a函数中对a函数重新赋值了一个新函数,第二次调用的a函数是这个新函数。 第一次改动的代码只是对b重新赋值了一个新函数。c变量并没有跟着改变。 第二次改动的代码,在f函数内被重新赋值的b是a函数闭包内的b。与外面var b = a()[0];全局作用域中的b是两个不同的变量。
看的不是很懂,我想再问一下。 先第一个。那这个是不是说明变量C拿到的其实是函数b的副本。后面函数b不管再怎么折腾变化都不会影响到变量C? 第二个。为什么他俩不是同一个呢?f函数内重新赋值的b是a函数当前的b函数。而var b = a()[0]中的b是a函数返回值数组中的第一个值。而a函数返回的数组有两个值,第一个是a函数中的b函数,第二个是a函数中的f函数。所以var b=a函数总的b函数。所以为什么他们两个不是同一个呢?
天际的海浪 2018-10-05
  • 打赏
  • 举报
回复
你原本的代码是在第一次调用a函数中对a函数重新赋值了一个新函数,第二次调用的a函数是这个新函数。 第一次改动的代码只是对b重新赋值了一个新函数。c变量并没有跟着改变。 第二次改动的代码,在f函数内被重新赋值的b是a函数闭包内的b。与外面var b = a()[0];全局作用域中的b是两个不同的变量。

87,993

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧