请教一个初级问题,关于对象引用在函数作用域中循环的行为 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
bigmusic
V2EX    Javascript

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

  •  
  •   bigmusic 2012-09-29 16:50:16 +08:00 4128 次点击
    这是一个创建于 4829 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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");
    13 条回复    1970-01-01 08:00:00 +08:00
    wong2
        1
    wong2  
       2012-09-29 17:55:28 +08:00   1
    我是这样理解的:

    一开始:

    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
        2
    wong2  
       2012-09-29 17:55:57 +08:00   1
    @wong2 好不容易打的空格都被吃了啊。。。
    bigmusic
        3
    bigmusic  
    OP
       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
        4
    bigmusic  
    OP
       span class="ago" title="2012-09-29 18:19:43 +08:00">2012-09-29 18:19:43 +08:00
    @wong2 你说的很对啊啊啊啊啊啊啊
    binux
        5
    binux  
       2012-09-29 18:24:30 +08:00
    「在for循环里我把parent改写成MYAPP会得到完全不同的结果」
    不同的结果又是什么?你想得到什么样的结果?
    bigmusic
        6
    bigmusic  
    OP
       2012-09-29 18:28:34 +08:00
    @binux
    如果换成MYAPP,你会得到MYAPP={x:3}的结果如果我没记错,因为MYAPP的指针被覆盖了

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

    parent变量保存的只是MYAPP的引用,用而不是对象本身。
    循环中的操作
    parent = parent[parts[i]];
    只是把parent指向的对象从MYAPP变为一个新的对象,MYAPP自然不会改变。C中指针不也是这样的么?
    要是parent改变会引起MYAPP那就是值传递了。
    binux
        8
    binux  
       2012-09-29 21:42:03 +08:00
    @bigmusic 这不应该叫指针被覆盖了吧,而且这和指针/引用什么东西都没有关系吧。这就好像
    MYAPP = 1
    然后
    MYAPP = 2
    一样理所当然,只是非常单纯地改变变量的值而已
    bigmusic
        9
    bigmusic  
    OP
       2012-09-30 00:53:39 +08:00
    @binux 在js中,对象的引用只能用指针来理解
    这里操纵不是MYAPP,而是parent这个指针指向MYAPP里面不同的对象
    bigmusic
        10
    bigmusic  
    OP
       2012-09-30 00:55:32 +08:00
    @chone
    都怪我脑袋不好使,被两个指针搞晕了...这是逻辑思维的问题,现在清晰多了,之前理解不了老怕自己对引用指针理解错误,奇怪问了两个做前端的都答不出来.._-_
    binux
        11
    binux  
       2012-09-30 01:19:05 +08:00
    @bigmusic 如果你「在for循环里我把parent改写成MYAPP」而产生MYAPP={x:3}的结果,原因只是简单地MYAPP的值被改变了罢了,这里根本不需要考虑什么对象,即使每次都产生新的拷贝,结果还是一样的。
    嘛,主要原因还是「在for循环里我把parent改写成MYAPP」这样的改法并不能揭示对象/引用这样的概念,与你的目的不符。
    chone
        12
    chone  
       2012-09-30 06:44:35 +08:00   1
    @bigmusic 主要是可能会受到c中指针的干扰,虽然指针在基本概念上和引用区别不大,但是在使用和赋值的时候会有很大差别。指针不管怎么赋值永远都只是个地址值,而引用在赋值的时候传递的是个类似指针的东西,但在使用变量的时候又会自动的对指针取值。
    bigmusic
        13
    bigmusic  
    OP
       2012-10-02 02:05:59 +08:00
    @chone 可能是我大概自学了一下C的缘故吧,那时候对指针印象很深,因为脑子不好使,用了几天时间去了解,然后看明白了兴奋了一段子,学JS前又看了一些公开课,有几集就是说C的指针,然后就混沌了...
    anyway,谢谢你们,现在开始攻BOM和DOM了~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5013 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 08:51 PVG 16:51 LAX 00:51 JFK 03:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86