使用默认参数时,参数会形成一个独立的作用域,此作用域与函数体中的作用域是平行关系
var x = 0;
function foo(x, y = function(){ x = 2; console.log(x); }) {
var x = 3;
y();
console.log(x);
}
foo();
console.log(x);
经过测试发现,此段代码如果使用babel编译成es5~输出结果为 2 2 0
这个结果和开头的结论并不符合~原因我暂时将其理解成babel的编译和原本es6的语法定义还是有点出入的
编译后的代码如下:
var x = 0;
function foo(x) {
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
x = 2;console.log(x);
};
var x = 3;
y();
console.log(x);
}
foo();
console.log(x);
而将es6代码直接复制到支持es6语法的浏览器中执行~得到结果为:
解释如下:
参数y有一默认值为一匿名函数,一整个参数列表形成一个独立的作用域,在匿名函数中没有定义x,故找到了外部的x即第一个参数x,然后赋值为2,并输出,所以第一行输出2,然后在foo函数体中声明了变量x并赋值为3,但此句过后执行匿名函数,并没有影响到foo函数体中的x最后最后输出3,这就是我一开始说的参数形成的独立作用域与函数体中的作用域是平行的匿名函数中的变量x在没有声明的情况下应该是沿着作用域链往上找而往上找的时候并不是找到foo函数体中定义的x而是找到形参列表中的第一个参数x,所以匿名函数中x = 2;这句并没有修改到foo函数体中的x的值,由此也证明foo函数体的作用域和形参列表的独立作用于并不是上下级关系
再来看个例子:
var x = 0;
function foo(x, y = function(){ console.log(x); x = 2; console.log(x); }) {
x = 3;
y();
console.log(x);
}
foo();
console.log(x);
结果为:
解释:
此例foo函数体中并没有用var重新声明变量x,所以此处x就是传进来的参数x(平时我们调用函数也是这种写法,至少调用函数的时候不会在函数体中对传进来的形参再声明一边,不然传进来干嘛~~)匿名函数中变量x没有声明,此处的x就是外层变量x即形参列表中第一个参数x,那最后得出3 2 2的结果也就不难理解了