Heim  >  Fragen und Antworten  >  Hauptteil

javascript – Problem beim Festlegen des Parameter-Standardwerts nach Funktion

var x = 1; 

function foo(x,y=function(){x=2;}){
    var x = 3;
    y();
    console.log(x); 
}
foo();

Dieser Code erscheint im es6-Buch von Lehrer Ruan Yifeng. Die Textbeschreibung besagt, dass das x in y und das x in var x = 3 nicht dasselbe sind Hier.
Entfernen Sie dann die Variable von var x = 3, und Sie können 2 ausgeben, was noch unverständlicher ist. . . Hoffe, es gibt eine Antwort

巴扎黑巴扎黑2663 Tage vor789

Antworte allen(7)Ich werde antworten

  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-07-05 10:39:59

    这里其实是涉及到 ES6 默认参数引入的一个中间作用域。这个问题当初阮一峰也弄错过,当然这里是正确的。

    中间作用域的目的就是防止默认参数被函数里面的变量污染。默认参数本意是为了让参数有默认值,假如函数内部的变量还能提升上来,那么默认参数就没意义了。具体的解释和例子可以看文章。

    所以看回问题,

    var x = 1; 
    
    function foo (x2, y = function () { x = 2; }) {
        var x = 3;
        y();
        console.log(x); 
    }
    foo();

    这里有三个作用域,把 x 由外到里标记出来就是:

    var x1 = 1; 
    
    function foo (x2, y = function () { x2 = 2; console.log(x2); }) {
        var x3 = 3;
        y();
        console.log(x3); 
    }
    foo();
    console.log(x1);

    假如没有了参数的 x,那么标记出来就是:

    var x1 = 1; 
    
    function foo (y = function () { x1 = 2; console.log(x1); }) {
        var x2 = 3;
        y();
        console.log(x2); 
    }
    foo();
    console.log(x1);

    Antwort
    0
  • 阿神

    阿神2017-07-05 10:39:59

    y()修改的是foo函数的参数x,并非全局x。(这里你可以在y()调用后,console.log(x),可发现全局x还是1.)
    问题就简单了: 1) 当用var x = 3时,foo里面的console.log(x)打印的就是foo里的局部变量x,y()修改的只是参数x,所以最终输出是局部变量x = 3
    2)当不用var时,foo里的所有x都指向参数x,而用y()把参数x修改为2,最终输出2

    Antwort
    0
  • PHP中文网

    PHP中文网2017-07-05 10:39:59

    y 的默认值改变的是全局变量的x;
    把var x= 3 的var去掉,就能输出2 是因为在foo的作用域内找不到x,所以在往上寻找,找到全局变量x,此时已被赋值为2

    Antwort
    0
  • 天蓬老师

    天蓬老师2017-07-05 10:39:59

    这是局部变量和全局变量生命周期的区别,方法里面的var x = 3;是局部变量,两个变量同名,方法体里面会使用局部变量,不会使用全局变量,所以输出的是var x = 3;这个x的值;当你去掉var x = 3;的var,说明在方法里面没有另外定义局部变量,使用的是全局变量x,而你方法参数又把这个全局变量值修改为2,所以输出为2;

    Antwort
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-07-05 10:39:59

    首先你要理解var操作符的定义,用var操作符定义的变量将成为定义该变量的作用域中的局部变量,也就是说,如果在函数中使用var定义一个变量,那么这个变量属于函数的一个局部变量,在函数退出时即被销毁,而不使用var直接定义的变量都将成为全局变量。
    另一个你要理解的概念是作用域链的问题,程序查找一个变量时,首先会在当前作用域内查找,若没有找到则顺着作用域链依次向上查找,遍历完都没有则报undefined。
    回到上面的代码,首先在全局作用域中利用var定义 x=1; x 即属于全局变量,接下来在函数foo内部定义了局部变量var x=3;X就属于函数的局部变量,接着执行y函数,对全局变量x进行修改赋值,这时x变为2,记住此时修改的是全局变量x而不是局部变量X,接下来打印x时,函数会依据作用域链先在函数内部查找x的值,找到x=3后即输出值,所以结果为3,若把var x=3的var去掉,则x变为全局变量,修改x就如同y函数中x赋值一样,这时只存在一个全局变量x,按照代码执行顺序,内部先修改全局变量X为3,然后y函数修改全局变量x为2,打印时,顺着作用域链,在函数内部没有找到x值,则接着在全局作用域中查找,此时X为2,所以结果为2

    Antwort
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-07-05 10:39:59

    var x = 1;
    
    function foo(x, y = function () { x = 2; }) {
        var x = 3;
        eval(`(${y.toString()})()`);
        console.log(x);
    }
    
    foo();

    Antwort
    0
  • 为情所困

    为情所困2017-07-05 10:39:59

    Antwort
    0
  • StornierenAntwort