JS之参数作用域

 这阵子因为要学习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。


参数:函数的扩展(注意这里的函数作为参数的情况是有问题的上面已经修改



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值