jtsai
V2EX  ›  问与答

js 作用域问题?

  •  
  •   jtsai · Jun 21, 2017 · 2817 views
    This topic created in 3249 days ago, the information mentioned may be changed or developed.
    window.name = 'abc';
    window.getName = function () {
    	alert(name)
    }
    window.getName() // abc
    
    var obj = {}
    obj.name = '123'
    obj.getName = function () {
    	alert(name)
    }
    obj.getName() // abc
    

    怪吗?

    25 replies    2017-06-22 09:59:44 +08:00
    deleteDB
        1
    deleteDB  
       Jun 21, 2017
    要写 alert(this.name)
    Fishdrowned
        2
    Fishdrowned  
       Jun 21, 2017 via Android
    不怡啊,这根本不是作用域,少年你混淆概念了。
    Rice
        3
    Rice  
       Jun 21, 2017
    这样你就觉得怪了?

    ```
    window.name = 'abc';
    var obj = {}
    obj.name = '123'
    obj.getName = function () {
    alert(this.name)
    }
    obj.getName() // 123
    var a = obj.getName;
    a();
    ```

    那这样呢?
    pandasjw
        4
    pandasjw  
       Jun 21, 2017 via Android
    这是全局变量的问题吧。。。
    jtsai
        5
    jtsai  
    OP
       Jun 21, 2017
    @Rice 你这个是 this 作用域的问题。可以被理解,我那个是变量加载的问题,为什么变量是这样加载的
    Rice
        6
    Rice  
       Jun 21, 2017
    @jtsai #5 可能是因为 js 没有类的概念吧。
    Rice
        7
    Rice  
       Jun 21, 2017   ❤️ 1
    @jtsai #5
    你这样想吧,js 不是现在这样设计
    而是对象方法调用的时候,先查找有没有当前对象的 name 值,然后没有再向上查找,这样会发生什么后果。
    这样的后果就是,如果这个对象一开始就没有 name 值,调用的时候就是全局变量 name
    结果被人后来修改了,加上 name,调用就是对象的属性 name。
    R18
        8
    R18  
       Jun 21, 2017
    你的意思是 应该 alert 123 吗?但是你的 123 是赋值给了一个对象的属性 对象属性的调用是 obj.name 你直接使用 name 是会逐层寻找这个变量 最后就找到了全局中的 name
    jin5354
        9
    jin5354  
       Jun 21, 2017
    在 ES6 前只有函数作用域和全局作用域,不要靠惯性和臆测写代码
    morethansean
        10
    morethansean  
       Jun 21, 2017
    连续两天见到同一个问题了,到底是谁教你们的调对象下面的函数,对象的属性就会被自动加到 scope chain 里啊?
    secondwtq
        11
    secondwtq  
       Jun 21, 2017 via Android
    @jtsai 你用 Python 写 method 访问实例变量不也是要写 self
    sliwey
        12
    sliwey  
       Jun 21, 2017
    不怪
    jtsai
        13
    jtsai  
    OP
       Jun 21, 2017
    @Rice
    @R18
    @jin5354
    @morethansean
    @secondwtq

    @Rice
    ```
    name = 'abc'

    class obj():
    def __init__(self):
    self.name = '123'

    def getName(self):
    print(name)

    obj().getName() # abc
    ```

    其实只是 js 的表达看起来有点怪 这样就很正常了。一直都是这样的。
    Rice
        14
    Rice  
       Jun 21, 2017
    @jtsai #13 我刚才突然想到动态语言是不是都这样,正打算看 Python 里的类是不是也是这样。
    luchenqun
        15
    luchenqun  
       Jun 21, 2017
    http://t.cn/Ro5N24k
    此问题到此终结!
    vincedd
        16
    vincedd  
       Jun 21, 2017 via iPhone
    @luchenqun 哈哈哈哈哈
    Rice
        17
    Rice  
       Jun 21, 2017
    @luchenqun #15 我看你是连我们在讨论什么都没看吧。
    jtsai
        18
    jtsai  
    OP
       Jun 21, 2017
    @luchenqun 老板,我这题跟 this 没有半毛钱关系
    BlackLynx
        19
    BlackLynx  
       Jun 21, 2017
    九楼十楼正解
    DUSTINTHEWIND
        20
    DUSTINTHEWIND  
       Jun 21, 2017
    这个昨天一个帖子的问题一模一样
    xxfan
        21
    xxfan  
       Jun 21, 2017
    少年可以看高程 4.2 节来理解一下执行环境和作用域链.
    我的理解是,作用域链,0 位是当前执行环境,也就是当前的 function(){} 花括号内的,显然 getName 这个函数内没有定义 name,找不到.
    然后再后一位,就是 window 这个执行环境了,window 中可以找到 name.返回 abc.

    obj 并不是 getName 的执行环境,不在作用域链内,它只是"调用环境",也就是调用这个函数的对象而已.(所以 this 的话指向 obj,而作用域不包含它)
    sunjourney
        22
    sunjourney  
       Jun 21, 2017
    为什么怪,有什么其它语言 obj.getName() 会是 123 ?不是 123 我才要惊了
    jtsai
        23
    jtsai  
    OP
       Jun 21, 2017
    @sunjourney
    我感觉有点怪是因为
    window instanceof Object // ture
    obj instanceof Object // ture
    window.toString === obj.toString // true

    咋一看差不多的
    xiaojunjor
        24
    xiaojunjor  
       Jun 21, 2017
    @luchenqun 哈哈哈哈哈哈,这个笑死我了
    Tokin
        25
    Tokin  
       Jun 22, 2017
    @sunjourney JavaScript 中的任何一个全局函数或变量都是 window 的属性。
    在 obj.getName 里调用的 name 是全局的 name 啊,如果要掉 obj 的 name 需要 this.name 或者 obj.name 不是吗?好奇。。。
    式作用域的问题?调错了的可能性大吧。。。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5458 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 99ms · UTC 05:52 · PVG 13:52 · LAX 22:52 · JFK 01:52
    ♥ Do have faith in what you're doing.