• Java Script 读书笔记 (三) 函数


    1. 函数作用域

        在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。

       变量v在函数内部定义,所以是一个局部变量,函数之外就无法读取。

       函数内部定义的变量,会在该作用域内覆盖同名全局变量。

      

    1 var v=1;
    2 function f(){
    3    var v=2;
    4    console.log(v);
    5 }
    6 
    7 f() //2
    8 v  // 1
    View Code

       注意,对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。

      

    1 if (true){
    2    var x=5;
    3 }
    4 console.log(x);  //5
    View Code

      上面代码中,变量x在条件判断区块之中声明,结果就是一个全局变量,可以在区块之外读取。

    2. 函数内部的变量提升

        与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的  头部。

      

     1 function foo(x){
     2   if (x>100){
     3       var tmp = x -100;
     4    }
     5 }
     6 
     7 
     8 //上面的代码等同于
     9 
    10 function foo(x){
    11    var tmp;
    12    if (x>100){
    13        tmp -x -100;
    14    };
    15 }
    View Code

    3. 函数本身的作用域

        函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。

       

     1 var a=1;
     2 var x =function(){
     3      console.log(a);
     4 };
     5 
     6 function f(){
     7     var a=2;
     8     x();
     9 }
    10 f() //1
    View Code

    上面的代码中, 函数x是在函数f的外部声明的,所以它的作用域绑定外层,内部变量a不会到函数f体内取值,所以输出1,而不是2.

    4. 默认值

       通过下面的方法, 可以为函数的参数设置默认值。

      

    1 function f(a){
    2    a=a||1;
    3    return a;
    4 }
    5 
    6 f("") //1
    7 f(0) //1
    View Code

       上面代码的||表示 “或运算”,即如果a有值,则返回a, 否则返回事先设定的默认值。
       这种写法会对a进行一次布尔运算, 只有为true时,才会返回a. 可是, 除了undefined以外,0、空字符、null等的布尔值也是false.也就是说,在上面的函数中,不能让a等于0或者空字符串, 否则在明明有参数的情况下,也会返回默认值 。为了避免这个问题, 可以采用下面更精确的写法.

      

    1 function f(a){
    2    (a!== undefined && a!==null)? a=a:a=1;
    3    return a;
    4 }
    5 
    6 f() //1
    7 f("") // ""
    8 f(0) //0
    View Code

    5. 传递方式

       传值传递 (passes by value): 函数参数是原始类型的值(Int,String,Boolean...), 在函数体内修改参数值,不会影响到函数外部。

       传址传递 (pass by reference) : 函数参数是复合类型的值(数组,对象,其他函数),在函数内部修改参数,将会影响到原始值。

      

      

    1 var obj={p:1};
    2 function f(0){
    3     o.p=2;
    4 |
    5 f(obj);
    6 obj.p //2
    View Code

      上面代码中, 传入函数f的是参数对象obj的地址,因此,在函数内部修改obj的属性p,会影响到原始值。

       注意,如果函数内部修改的,不是参数对象的某个属性, 而是替换掉整个参数,这时不会影响到原始值,例: 

    1 var obj=[1,2,3];
    2 function f(0){
    3   o=[2,3.4];
    4 }
    5 f(obj);
    6 
    7 obj //[1,2,3]
    View Code

       上面代码中, 在函数f内部,参数对象obj被整个替换成另一个值,这时不会影响到原始值,因为形式参数(o)与实际参数obj存在一个赋值关系。

      如果需要对某个原始类型的变量, 获取传址传递的效果,可以将它写成全局对象的属性:

    1 var a=1;
    2 function f(p){
    3    window[p] =2;
    4 }
    5 f("a");
    6 
    7 a//2
    View Code

      上面代码中, 变量a本来是传值传递,但是写成window对象的属性,就达到了传址传递的效果。

    6. 同名参数

        如果有同名的参数,则取最后出现的那个值。例:   

    1 function f(a,a){
    2     console.log(a);
    3 }
    4 f(1,2) //2
    View Code

        即使后面的a没有值或被省略,也是以其为准.

        

    1 function f(a,a){
    2     console.log(a);
    3 }
    4 f(1) // undefined
    View Code

       调用函数f的时候,如果没有提供第二个参数,a的取值就变成了undefined.这时, 如果要获得第一个a的值,可以使用arguments对象。
      

    1 function f(a,a){
    2      console.log(arguments[0]);
    3 }
    4 f(1) //1
    View Code

      

  • 相关阅读:
    从 0 配置 webpack(一)
    Redux
    React Hooks 全解(二)
    日本人要把核污水排进大海,我突然想到几个问题
    突然发现,我的代码还花花绿绿的,挺好看的
    Ghidra ,改道吧,我也准备改道这玩意了
    语音控制?这,看起来很眼熟。
    winafl 工具的编译
    关于 TX 的 WeGame 的一点疑问
    新年的第一个随笔,随便写写吧
  • 原文地址:https://www.cnblogs.com/cheese320/p/8038410.html
Copyright © 2020-2023  润新知