这阵子因为要学习React Native,而RN必备的知识就是JS,所以开始学习起来了Js,在此声明写博客就是为了更好的学习,总结一些我学习过程中知识点,有不同意见的请尽情发表!
1.普通参数
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2) // 2
上面代码中,参数y
的默认值等于变量x
。调用函数f
时,参数形成一个单独的作用域。在这个作用域里面,默认值变量x
指向第一个参数x
,而不是全局变量x
,所以输出是2
。
再看下面的例子。
let x = 1;
function f(y = x) {
let x = 2;
console.log(y);
}
f() // 1
上面代码中,函数f
调用时,参数y = x
形成一个单独的作用域。这个作用域里面,变量x
本身没有定义,所以指向外层的全局变量x
。函数调用时,函数体内部的局部变量x
影响不到默认值变量x
。
如果此时,全局变量x
不存在,就会报错。
function f(y = x) {
let x = 2;
console.log(y);
}
f() // ReferenceError: x is not defined
下面这样写,也会报错。
var x = 1;
function foo(x = x) {
// ... }
foo() // ReferenceError: x is not defined
上面代码中,参数x = x
形成一个单独作用域。实际执行的是let x = x
,由于暂时性死区的原因,这行代码会报错”x 未定义“。
2 函数作为参数
在此说明下,资料函数的扩展 说在这种情况下也可以把参数看成独立的作用域,这个我还不确定
我们来看下面的实例:
var fo = 'outer'; function bar(func = x => fo) { console.log(func());// undefined let fo = 'inner'; console.log(func()); return func(); } bar();//inner
结果和资料上说明的期望结果不一样,在外部作用域和内部作用域都用一个变量 fo,在let fo ='inner'之前调用func()打印的结果是undefined ,在之后调用func()函数也没有打印出的outer结果,而是inner,也就是说,此时在let fo = 'inner'之前,fo压根就不存在没有声明,也没有去指向外部的fo变量,
在let fo = 'inner'之后,才有了fo变量,且其值为inner,那我们把let fo = 'inner'去掉呢?如下:
function bar2(func = x => fo) { console.log(func());// outer // let fo = 'inner'; console.log(func()); //outer return func(); } bar2();//outer
好吧,在去掉let fo = 'inner'后,返回结果是outer,也就是说,此种情况下,函数func()在bar2内部没有发现fo变量,直接指向外部变量fo。那我们再看种情况:
var x = 1; function foo(x, y = function() { x = 2; return x; }) { //foo调用时没有 传递参数 打印显示 undefined 正常 console.log(x); //undefined //返回的是函数y内部的x值,不是外部的x值 console.log(y()); //2 //????? 2 console.log(x); //2 var x = 3; // x 被赋值为 3 打印 3 正常 console.log(x); //3 // x值 3 被函数y改为 2 打印 2 console.log(y());//2 //此时 x = 2 console.log(x);//2 } foo();
上面的代码在var x =3 之前打印x的值变为了2,毫无疑问这个2肯定是来自函数y,但这个x是函数y的局部变量啊,那么foo一般是不能访问的啊,那么会不会是全局变量的x,那我们在调用foo()之后,看看全局变量x值是否改变了:
console.log(x);//1
没有看错,结果就是1 ,那证明全局变量的x值是没有改变的,也就是说使用的不是全局的那个x,
那么只有一种情况了,就是foo函数是可以访问函数y中的x,那么我们验证下这个猜想:
function foo2() { m = 222; return m ; } foo2(); console.log(m);//222
上面的代码返回的是222,这证明我们的猜想是正确的。那m不是foo2中的变量吗?为什么在函数为能够直接访问呢?其实这个和Js机制有关,未声明的变量直接进行初始化,js机制会把这个变量添加到全局变量列表中,如果 使用var进行了声明那么Js机制会把这个变量添加到最近的可用环境中,例如上面的m就添加到了全局变量列表中,所以在函数foo2也可以访问,我们再看如果上述代码添加var声明会有怎么的效果呢:
function foo2() { var m = 222; return m ; } foo2(); console.log(m);
结果是程序直接崩溃了,提示 m is not defined。
参数:函数的扩展(注意这里的函数作为参数的情况是有问题的上面已经修改)