Java Script 读书笔记 (三) 函数
2017-12-14 16:28 钱先生 阅读(163) 评论(0) 编辑 收藏 举报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
注意,对于var
命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。
1 if (true){ 2 var x=5; 3 } 4 console.log(x); //5
上面代码中,变量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 }
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
上面的代码中, 函数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
上面代码的||表示 “或运算”,即如果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
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
上面代码中, 传入函数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]
上面代码中, 在函数f内部,参数对象obj被整个替换成另一个值,这时不会影响到原始值,因为形式参数(o)与实际参数obj存在一个赋值关系。
如果需要对某个原始类型的变量, 获取传址传递的效果,可以将它写成全局对象的属性:
1 var a=1; 2 function f(p){ 3 window[p] =2; 4 } 5 f("a"); 6 7 a//2
上面代码中, 变量a本来是传值传递,但是写成window对象的属性,就达到了传址传递的效果。
6. 同名参数
如果有同名的参数,则取最后出现的那个值。例:
1 function f(a,a){ 2 console.log(a); 3 } 4 f(1,2) //2
即使后面的a没有值或被省略,也是以其为准.
1 function f(a,a){ 2 console.log(a); 3 } 4 f(1) // undefined
调用函数f的时候,如果没有提供第二个参数,a的取值就变成了undefined.这时, 如果要获得第一个a的值,可以使用arguments对象。
1 function f(a,a){ 2 console.log(arguments[0]); 3 } 4 f(1) //1