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 · 3460 次点击
    这是一个创建于 4225 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
       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   ·   我们的愿景   ·   实用小工具   ·   1497 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:16 · PVG 01:16 · LAX 10:16 · JFK 13:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.