请教一个初级问题,关于对象引用在函数作用域中循环的行为

2012-09-29 16:50:16 +08:00
 bigmusic
OK,问了两个大神,一个不回答一个没搞懂,现在公开问一下,本来想问个朋友的朋友,但朋友说可能问题太弱智会比那个朋友的朋友无视....

JavaScript里的对象引用暂时为止我的理解是指针,引用对像的引用就是复制一个指针,而对象是宇宙的,不是地球(函数作用域)的,所以我理解无论是在函数作用域内定义的指针还是全局window下定义的指针,都是指向同一个对象.

但我发现在函数作用域内循环语句中的对象指针行为和全局指针行为不同,很费解...

这个是YUI的一个家伙写的模拟命名空间的函数,我想问的不是函数本身的功能,而是MYAPP和parent这两个指针,在for循环里我把parent改写成MYAPP会得到完全不同的结果...-

var MYAPP = MYAPP || {};

MYAPP.namespace = function(ns_string) {
var parts = [],
parts = ns_string.split("."),
parent = MYAPP,
i;

if (parts[0] === "MYAPP") {
parts = parts.slice(1);
};
for (i = 0; i < parts.length; i += 1) {
parent[parts[i]] = {
x: i + 1
};
parent = parent[parts[i]]; //////////??????????????????????????

};

//return parent;
};
MYAPP.namespace("MYAPP.module1.module2.module3");
3514 次点击
所在节点    JavaScript
13 条回复
wong2
2012-09-29 17:55:28 +08:00
我是这样理解的:

一开始:

MYAPP --> {}

parent = MYAPP执行之后:

MYAPP --> {} <-- parent

循环一次之后:

MYAPP --> {
module1: {x:1} <-- parent
}

循环两次之后:

MYAPP --> {
module1: {
x:1,
module2: { x:2 } <-- parent
}
}
依次类推

如果在for里把parent改写成MYAPP,`MYAPP = MYAPP[parts[i]]` 执行时会造成MYAPP被覆盖掉,不再指向最外层的对象。。
wong2
2012-09-29 17:55:57 +08:00
@wong2 好不容易打的空格都被吃了啊。。。
bigmusic
2012-09-29 18:18:30 +08:00
已解决,这并不是一个简单的相等引用的问题,因为循环中的指针parent不断改变,而MYAPP这个指针是没有变的,我的理论没有错,这里只是两个指针,一个全局不变,一个局部随循环改变的不同
parent在第一次循环指向MYAPP.module1,第二次循环指向MYAPP.module1.module2,第三次指向MYAPP.module1,module2.module3
可以在循环内加上console检测parent.x的变化观察之

这是一个脑子不够用的逻辑问题.....我恨我不是谢耳朵,可以继续DOMBOM了
bigmusic
2012-09-29 18:19:43 +08:00
@wong2 你说的很对啊啊啊啊啊啊啊
binux
2012-09-29 18:24:30 +08:00
「在for循环里我把parent改写成MYAPP会得到完全不同的结果」
不同的结果又是什么?你想得到什么样的结果?
bigmusic
2012-09-29 18:28:34 +08:00
@binux
如果换成MYAPP,你会得到MYAPP={x:3}的结果如果我没记错,因为MYAPP的指针被覆盖了

再有,我提的这个问题也是不成立的,将var parent=MYAPP;搬到全局对结果没影响,这只是两个指针的戏法而已~
chone
2012-09-29 19:16:13 +08:00
在javascript里这个东西叫引用,其实就是指针的概念。基本类型String, Number, Boolean之类以外的复杂类型赋值操作传递的都是引用。

parent变量保存的只是MYAPP的引用,用而不是对象本身。
循环中的操作
parent = parent[parts[i]];
只是把parent指向的对象从MYAPP变为一个新的对象,MYAPP自然不会改变。C中指针不也是这样的么?
要是parent改变会引起MYAPP那就是值传递了。
binux
2012-09-29 21:42:03 +08:00
@bigmusic 这不应该叫指针被覆盖了吧,而且这和指针/引用什么东西都没有关系吧。这就好像
MYAPP = 1
然后
MYAPP = 2
一样理所当然,只是非常单纯地改变变量的值而已
bigmusic
2012-09-30 00:53:39 +08:00
@binux 在js中,对象的引用只能用指针来理解
这里操纵不是MYAPP,而是parent这个指针指向MYAPP里面不同的对象
bigmusic
2012-09-30 00:55:32 +08:00
@chone
都怪我脑袋不好使,被两个指针搞晕了...这是逻辑思维的问题,现在清晰多了,之前理解不了老怕自己对引用指针理解错误,奇怪问了两个做前端的都答不出来.._-_
binux
2012-09-30 01:19:05 +08:00
@bigmusic 如果你「在for循环里我把parent改写成MYAPP」而产生MYAPP={x:3}的结果,原因只是简单地MYAPP的值被改变了罢了,这里根本不需要考虑什么对象,即使每次都产生新的拷贝,结果还是一样的。
嘛,主要原因还是「在for循环里我把parent改写成MYAPP」这样的改法并不能揭示对象/引用这样的概念,与你的目的不符。
chone
2012-09-30 06:44:35 +08:00
@bigmusic 主要是可能会受到c中指针的干扰,虽然指针在基本概念上和引用区别不大,但是在使用和赋值的时候会有很大差别。指针不管怎么赋值永远都只是个地址值,而引用在赋值的时候传递的是个类似指针的东西,但在使用变量的时候又会自动的对指针取值。
bigmusic
2012-10-02 02:05:59 +08:00
@chone 可能是我大概自学了一下C的缘故吧,那时候对指针印象很深,因为脑子不好使,用了几天时间去了解,然后看明白了兴奋了一段子,学JS前又看了一些公开课,有几集就是说C的指针,然后就混沌了...
anyway,谢谢你们,现在开始攻BOM和DOM了~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/49001

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX