代码之家  ›  专栏  ›  技术社区  ›  Mutation Person

关于这个javascript,后台发生了什么?

  •  1
  • Mutation Person  · 技术社区  · 15 年前

    我今天回顾了一些,当时我遇到了以下惯例:

    TestParam(1);
    
    function TestParam(p){
        var p = p + 1;
        alert(p);   // alerts '2'
    }
    

    现在,很明显,开发人员并不打算在函数中Delcare“p”,而是可能意味着:

        p = p + 1;
    

    但代码仍然有效,即警报值为“2”。所以我开始思考。在以下情况下会发生什么:

    var a = 1;
    TestParam(a);
    alert(a);  // alerts "1"
    
    function TestParam(p){
        var p = p + 1;
        alert(p);   // alerts '2'
    }
    

    再次提醒是我怀疑的(正如上面的评论所暗示的)。所以我很好奇如果我使用一个物体会发生什么:

    var a = { b: 1 };
    TestParam(a);
    alert(a.b);  //alerts 1
    
    function TestParam(p) {
        var p = {b:p.b + 1};
        alert(p.b); //alerts 2
    }
    

    因此,在本例中,javascript已经“记住”了变量 a ,即使当它作为 p , 重新声明。

    现在,如果我在函数中执行了以下操作,那么两个警报都将是“2”

        p.b++;
        //var p = {b:p.b + 1};
    

    也就是说,它会修改成员 b 原始对象的。我明白了。之前的场景让我困惑!

    我意识到这是一个假设性的问题,不太可能具有实际的实用性,但它仍然让我很好奇,到底在后台发生了什么,以及javascript是如何精确地定义和引用这些变量的。

    有什么想法吗?

    3 回复  |  直到 15 年前
        1
  •  5
  •   Jason Orendorff Oliver    15 年前

    变量的作用域是JavaScript中的封闭函数。你可以随时申报。

    对象是 绑定到变量;许多变量可以引用同一对象。(有时称之为 混叠 这就是上一个例子中发生的事情。javascript没有“记住”变量 a 一点也不;更确切地说, p 引用同一对象,因此当通过 ,您可以通过查看这些更改 .

    下面是一个对你更有意义的例子。有时一个人有不止一个身份。

    var Clark = new Person;
    var Superman = Clark;  // Maybe not everybody needs to know these two are
                           // the same person, but they are.
    Clark.eyes = "brown";
    alert(Superman.eyes);  // should be brown, right?
    

    了解你所使用语言的规则有着巨大的“现实世界的有用性”。不理解这两个规则是很多混乱和错误的根源。

        2
  •  1
  •   slebetman    15 年前

    javascript通常通过引用将所有参数传递给函数 除了 当参数是数字或字符串时。javascript通行证 数值和字符串 这就是为什么你的第一个例子是这样工作的。

        3
  •  1
  •   inxilpro    15 年前

    我相信你的密码有错。我想你的意思是:

    function TestParam(p) {
        var p = {b:p.b + 1}; // p.b, not p.a (p.a == undefined)
        alert(p.b);
    }
    

    在您的示例中:

    var a = { b: 1 }; // "a" is defined in the global scope
    TestParam(a);
    alert(a.b);  // alerts 1
    
    function TestParam(p) {
        var p = {b:p.a + 1}; // "p" is defined in TestParam()'s scope
        /* But not until after the expression on the right side of the assignment
           has completed--that's why you can use p.a 
        alert(p.a); //alerts 2
    }
    

    首先,“p”作为对全局变量“a”的引用传递,然后在第一行中重新定义它。例如:

    var a = { b: 1 };
    alert(a.b); // Alerts 1
    TestParam(a);
    alert(a.b); // Alerts 2
    TestParam(a);
    alert(a.b); // Alerts 3
    
    function TestParam(p) {
        p.b++;
    }