javascript – Problem beim Festlegen des Parameter-Standardwerts nach Funktion
巴扎黑
巴扎黑 2017-07-05 10:37:59
0
7
833
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

巴扎黑
巴扎黑

Antworte allen(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

扔个三星炸死你
var x = 1;

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

foo();
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage