为什么 js 对象里的方法不查找对象里的属性? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rebeccaMyKid
V2EX    问与答

为什么 js 对象里的方法不查找对象里的属性?

  •  
  •   rebeccaMyKid 2017-06-20 10:54:29 +08:00 2000 次点击
    这是一个创建于 3048 天前的主题,其中的信息可能已经有所发展或是发生改变。

    对于作用域链的问题,这个代码我理解:

    var name = 23; function sayName(){ return name; } console.log(sayName()); //23 

    当前函数作用域没有name就往上找。

    但是,这个为什么不返回对象的 name 属性?

    var name = 23; var obj = { name: 666, getName: function(){ return name; } }; console.log(obj.getName()); //23 

    加上

    return this.name; 就可以

    13 条回复    2017-06-21 07:56:56 +08:00
    jtsai
        1
    jtsai  
       2017-06-20 11:06:48 +08:00
    var name 是局部变量
    name 是全局变量 (没有加 var )

    这段代码,你在 obj 里定义的 name 跟 在 obj 外 定义的 name 都是 window.name
    jtsai
        2
    jtsai  
       2017-06-20 11:08:30 +08:00
    噢 我搞错
    mufeng
        3
    mufeng  
       2017-06-20 11:09:48 +08:00
    jtsai
        4
    jtsai  
       2017-06-20 11:12:00 +08:00
    name: 666, 不是定义变量 name,而是定义 obj 对象的属性 name 的值 = 666

    getName: function(){ return name; } 这段是访问 name 这个变量,不是范围 obj.name 这个属性
    acthtml
        5
    acthtml  
       2017-06-20 11:13:49 +08:00
    this 指向上级对象。
    var 的作用域在 function 或全局中。
    acthtml
        6
    acthtml  
       2017-06-20 11:14:25 +08:00
    @acthtml 应该这么说,this 指向运行时的上级对象。
    morethansean
        7
    morethansean  
       2017-06-20 11:16:39 +08:00   1
    谁给你说你调一个对象下的函数对象的属性就会被自动加到 scope chain 里的……
    DUSTINTHEWIND
        8
    DUSTINTHEWIND  
       2017-06-20 11:33:01 +08:00
    我觉得应该是这样:这里面一共两个域:1. global 2. getName
    getName 返回的 name 先在 getName 域里面查找,没找到,就到 global 域上找,找到了,于是打印 23
    但是为什么不返回 obj 的 name,这.......总觉得哪里有点奇怪
    forgcode
        9
    forgcode  
       2017-06-20 12:02:15 +08:00
    bj.getName()这个方法的执行环境在 window!
    基本判断环境
    1.是不是 new 的
    2.是不是通过 call、apply
    3.在其他上下文环境调用
    4.然后就是默认,用严格模式就 undefined 不然就全局对象
    noe132
        10
    noe132  
       2017-06-20 12:33:57 +08:00
    因为 js 的对象是动态对象。如果 obj 本来没有 name 这个属性,你的 getname 依赖的是外部的变量 name 的值

    若这个 obj 被其他地方修改,添加了个 name 属性,那么问题来了,要返回 obj.name 还是 obj 外部的变量 name 的值呢?

    如果默认会返回 obj.name,那么就算 obj.name 没有定义,它的值也是 undefined,那到底是返回外部的值还是返回 undefined 呢?

    所以 JS 中的作用域是在函数定义的时候确定的,不是函数调用的时候确定的。而且不像 Java,就算没有显示指定 this,作用域没找到相应变量时会自动找当前对象上的值,因为 Java 的对象都是固定写好的类,属性名和方法名都是写死的,不会出现上述问题。

    况且,方法在对象上必须以 obj.method()的方式调用时 this 才指向 obj,如果 var method = obj.method; method(); method()中的 this 在非严格模式下是 global 对象,严格模式下是 undefined。
    rebeccaMyKid
        11
    rebeccaMyKid  
    OP
       2017-06-20 14:34:55 +08:00
    @morethansean 嗯!
    vincedd
        12
    vincedd  
       2017-06-21 07:46:39 +08:00 via iPhone
    return this.name 等价于 return obj.name,调用问题中调用 getName 的时候,当前作用域是 getName,上一级的作用域应该是 window,这么理解对不对?
    rebeccaMyKid
        13
    rebeccaMyKid  
    OP
       2017-06-21 07:56:56 +08:00 via iPhone
    @vincedd 应该是这样的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2549 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 13:18 PVG 21:18 LAX 06:18 JFK 09:18
    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