以为自己弄懂了传值与传址,结果似乎不是这样的...

many_problems 2014-05-03 06:53:46
看js犀牛书,说是基本类型按照传值,引用类型按照传址,引用类型的传址本质上还是传值,因为这个值是一个引用,也即地址。自以为这很容易理解啊。今天看js高级程序设计,第三版71页的代码,实在不能理解,求高人指导:

<script>
function setName(obj){
obj.name="Nicholas";
obj=new Object();
obj.name="Greg";
}
var person=new Object();
setName(person);
alert(person.name); //Nicholas
</script>

输出为什么不是“Greg”?麻烦懂得人详细解释一下
...全文
596 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33514038 2016-10-09
  • 打赏
  • 举报
回复
Monkey_D_Jie 2016-07-12
  • 打赏
  • 举报
回复
额。。。。看得迷迷糊糊的
chen870201 2014-05-05
  • 打赏
  • 举报
回复
越来越迷糊了
aqbeyond 2014-05-05
  • 打赏
  • 举报
回复
<script> function setName(obj){ obj.name="Nicholas"; obj=new Object(); obj.name="Greg"; return obj; } var person=new Object(); person=setName(person); alert(person.name); //Nicholas </script> 这样就是你想要的效果吧,哈哈。
CC11001100 2014-05-04
  • 打赏
  • 举报
回复
引用 10 楼 many_problems 的回复:
[quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?[/quote] 第一个问题上面那哥们有图有真相解释得非常明白了,第二个说实话没看懂你说的什么意思,个人理解所谓形参只是声明了一个函数作用域的变量,与函数中其它局部变量所不同的是这个变量在调用时就使用实参的值进行初始化,当然,还要说句欠揍的话,上面纯粹我瞎猜的未经过实际验证....
many_problems 2014-05-04
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
[quote=引用 10 楼 many_problems 的回复:] [quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?[/quote] person引用的那个对象,一开始也被obj引用。后来obj应用了另外一个对象,但是这个obj的新的引用并不会修改到person引用。[/quote]obj只是一个形参啊,调用setName时,obj不是被person替代了吗,obj已经没了啊。person传入函数,obj被person取代,执行person.name="Nicholas';person=new Object();person.name="Greg";啊,我的疑问再这里啊。。。。
  • 打赏
  • 举报
回复
引用 10 楼 many_problems 的回复:
[quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?[/quote] person引用的那个对象,一开始也被obj引用。后来obj应用了另外一个对象,但是这个obj的新的引用并不会修改到person引用。
vincentguo_ 2014-05-04
  • 打赏
  • 举报
回复
等我想想怎么和你讲为啥obj存在的问题吧。。。
many_problems 2014-05-04
  • 打赏
  • 举报
回复
引用 1 楼 l676331991 的回复:
你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?
many_problems 2014-05-04
  • 打赏
  • 举报
回复
引用 7 楼 vincentguo_ 的回复:
楼主没看懂我的比喻么,意思和5楼是一样的,好纠结。。。 看看这个图能明白么
你的图很好理解,解释了为什么输出Nicholas。我的疑问又来了,obj只是个形参啊,person传进去后,实参会代替形参啊,为什么obj这个形参还一直存在呢?
l676331991 2014-05-04
  • 打赏
  • 举报
回复
引用 12 楼 many_problems 的回复:
[quote=引用 11 楼 sp1234 的回复:] [quote=引用 10 楼 many_problems 的回复:] [quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?[/quote] person引用的那个对象,一开始也被obj引用。后来obj应用了另外一个对象,但是这个obj的新的引用并不会修改到person引用。[/quote]obj只是一个形参啊,调用setName时,obj不是被person替代了吗,obj已经没了啊。person传入函数,obj被person取代,执行person.name="Nicholas';person=new Object();person.name="Greg";啊,我的疑问再这里啊。。。。[/quote] 谁告诉你形参要被实参代替,谁说“代替”是你所理解的这个意思?“代替”到了你这里居然又转化为实参“取代”了形参?? 你的理解太丰富了!所谓的“形参要被实参代替”指的就是形参的值要被实参的值所赋予!!早和你说了函数的参数传递和“=”赋值符号是一样的意思,不明白也不看大家的回帖么?函数的参数和函数内部的局部变量是一个意思,参数传递过程就是变量的赋值过程呀亲呀个亲!
CC11001100 2014-05-04
  • 打赏
  • 举报
回复
引用 13 楼 u011092785 的回复:
[quote=引用 10 楼 many_problems 的回复:] [quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
obj只是个形参啊,它不是被实参person替代么,为什么它一直存在?实参传进去以后,形参也该没了啊,形参只是一个名字啊,为什么还会一直存在?[/quote] 第一个问题上面那哥们有图有真相解释得非常明白了,第二个说实话没看懂你说的什么意思,个人理解所谓形参只是声明了一个函数作用域的变量,与函数中其它局部变量所不同的是这个变量在调用时就使用实参的值进行初始化,当然,还要说句欠揍的话,上面纯粹我瞎猜的未经过实际验证....[/quote] 妈蛋,我完蛋了原来他们没骗俺我智商真的有问题,好吧,现在不是说这个的时候,终于自认为看明白了,其实我也是刚学几天以下纯粹个人瞎猜观点就当看着玩吧,扯远点,函数参数只是实现数据的传递方式之一,既然我要传的是数据,那我管你传值还是传址,我找个家什一股脑儿盛着就是了,如果是值我拿来就用了如果是地址我再间接访问(如何区分是语言的事),当然传过来之后就不关外面的事了,(我理解的变量也只是容器,因此对你所说的变量传进去很不能理解,我觉得所有的所有都只是对数据进行处理,传的都是数据,或者叫做数值?,把ds指过去就当做数据啦~~~~),因此对于函数来说你传过来什么类型的数据我就拿相应的容器盛着就是了(用篮子盛水属于行为艺术==)(这个比喻很不贴切啊,大多时候只是复制,现实中可没有这好事),所以就会产生这样的结果:对于值,它俩是俩不同的变量,改了就改了,关外面的X事。对于引用,若改函数作用域变量的值自然不关外面啥事(对照为obj的重新赋值),可是若通过这引用改了外面那位“大哥”罩着的“地盘”,自然就有点特别了(大哥微信何在!哦不对,大哥威信何在!),,对照你前面说的“一切都是传值而已”的思想,应该很好理解吧,我去,感觉自己很啰嗦貌似还没说清楚……郁闷,肯定是理解不够深刻。好吧,但愿不是理解完全错误。
vincentguo_ 2014-05-04
  • 打赏
  • 举报
回复
简单的理解如 15楼所说, 形参也是局部变量,局部变量当函数执行的时候是给分配空间的,当然函数执行结束会结束他的生命。 如果你一定要深究这个问题,请先自行搜索 内存分配 函数调用 形参 实参等资料。虽然可能很多是C++相关资料,但原理一样的
keatkeat1987 2014-05-03
  • 打赏
  • 举报
回复
function setName(obj) { obj.name = "Nicholas"; alert(obj === person); //true obj = new Object(); alert(obj === person); //false obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //Nicholas
vincentguo_ 2014-05-03
  • 打赏
  • 举报
回复
楼主没看懂我的比喻么,意思和5楼是一样的,好纠结。。。
看看这个图能明白么
many_problems 2014-05-03
  • 打赏
  • 举报
回复
引用 4 楼 u011461314 的回复:
function setName(obj){ obj.name="Nicholas"; obj=new Object(); obj.name="Greg"; } var person=new Object(); setName(person); alert(person.name); //Nicholas alert(obj.name);
obj只是一个参数名,调用时用person替代,你让我alert(obj.name)当然不会有结果。我的回复中说出了我的理解,如果你懂得话,能不能指出我的理解哪个环节出错了?谢谢。。。
l676331991 2014-05-03
  • 打赏
  • 举报
回复
引用 3 楼 many_problems 的回复:
[quote=引用 1 楼 l676331991 的回复:] 你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
第二行让obj引用到内存里的一个新对象的地址,即此时obj里存储的是一个新对象的地址值,然后通过这个引用为新对象添加name属性并赋值为"Greg"。这写不能解决我的疑问啊,只会加深我的疑问。调用函数时,我们将person传入,然后通过person这个引用为它锁引用的对象添加name属性并赋值“Nicholas”,然后又让person指向内存里的新对象,那么此时person已经不再引用以前的那个name属性为“Nicholas”的对象了啊,而是引用name属性为“Greg”的对象了。alert时不就应该输出“Greg”吗?你说是不是,问题出在哪呢?[/quote] 值传递呀值传递。 person传递给obj,传递的是引用,是person指向的那块内容的地址,说白了现在有两个标识符指向这块内存的首地址,一个是person,一个是obj。 obj = new Object(); 这一条语句执行之后,obj指向了新的内存地址,那与person这个标识符何干?person这个标识符还是指向原来那片内存呀!obj移情别恋了,person还苦苦恋着它! 画一画内容引用的图就一目了然了!
zhjdg 2014-05-03
  • 打赏
  • 举报
回复
function setName(obj){ obj.name="Nicholas"; obj=new Object(); obj.name="Greg"; } var person=new Object(); setName(person); alert(person.name); //Nicholas alert(obj.name);
many_problems 2014-05-03
  • 打赏
  • 举报
回复
引用 1 楼 l676331991 的回复:
你弄懂了参数的值传递,就没明白其实“=”赋值符号也是一样的意思么? setName的第二行干了什么?
第二行让obj引用到内存里的一个新对象的地址,即此时obj里存储的是一个新对象的地址值,然后通过这个引用为新对象添加name属性并赋值为"Greg"。这写不能解决我的疑问啊,只会加深我的疑问。调用函数时,我们将person传入,然后通过person这个引用为它锁引用的对象添加name属性并赋值“Nicholas”,然后又让person指向内存里的新对象,那么此时person已经不再引用以前的那个name属性为“Nicholas”的对象了啊,而是引用name属性为“Greg”的对象了。alert时不就应该输出“Greg”吗?你说是不是,问题出在哪呢?
vincentguo_ 2014-05-03
  • 打赏
  • 举报
回复
我是 初学,说错了还望大家指正。可能比喻的有点乱哈 举例吧: 先执行顺序 1. var person=new Object(); 比喻为天津旁边有一块地方(new 申请来的空间地址)给北京(person)了 2. setName(person); ---- 这里person和obj是指向了同一块空间,只是别名不同罢了 比喻为 给北京那块地也叫 首都(obj) 相当于同一块空间,有两个名字 obj.name="Nicholas"; ---- 北京或者叫首都的那块地里有个村子(name)叫 Nicholas obj=new Object(); ------ 又申请了一块新地方叫首都了,这个时候第一次申请的那块空间就只剩北京一个名字了,而首都这个名字给了这第二次申请的空间 obj.name="Greg"; ---- 第二次申请的空间(首都 obj)里有个村子叫Greg alert(person.name); 你问北京那个村叫啥? 答案: Nicholas
加载更多回复(1)

87,915

社区成员

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

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