javascript - 函数设置参数默认值的问题
巴扎黑
巴扎黑 2017-07-05 10:37:59
0
7
747
var x = 1; function foo(x,y=function(){x=2;}){ var x = 3; y(); console.log(x); } foo();

这段代码出现在阮一峰老师写的es6那本书,最后输出3,文字说明说y中的x和var x = 3;的x不是同一个x,这儿有点不理解。
然后把var x= 3 的var去掉,就能输出2,更不理解了。。。希望能有解答

巴扎黑
巴扎黑

全部回复 (7)
女神的闺蜜爱上我

这里其实是涉及到 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);
    阿神

    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

      Ty80

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

        Peter_Zhu

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

          扔个三星炸死你

          首先你要理解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

            扔个三星炸死你

            雷雷

              最新下载
              更多>
              网站特效
              网站源码
              网站素材
              前端模板
              关于我们 免责声明 Sitemap
              PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!