JavaScript函数及作用域

知识内容:

1.JavaScript函数

2.JavaScript作用域

参考资料:《JavaScript高级程序设计》

一、JavaScript中的函数

1.函数的定义

学完python后,对函数的定义一定不再陌生了,函数对于任何一个语言来说都是核心的概念。通过函数我们可以封装任意多条语句,而且可以在任何地方任何时候调用执行。JavaScript中的函数使用function来声明定义,函数的基本语法如下:

1 function functionName (arg0, arg1, ..., argN){
2     statements
3 }
4 
5 // 以下是一个函数示例:
6 function sayHi(name, message){                         // 定义函数
7     alert("Hello " + name + ", " + message);
8 }
9 sayHi("wyb", "Good morning!");  // 调用函数

或者以下面的这种方式定义函数:

1 sayHi = function() {
2     console.log("Hello, world!");  
3 }
4 
5 sayHi();

2.函数的参数与返回值

(1)函数的参数

像上面的例子中出现的参数都叫命名参数,类似python中的普通参数,在这里不做详细解释

JavaScript中函数的参数在内部是用一个数组表示,函数接受的始终是这个数组,而不关心数组中包含哪些参数。实际上函数可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数

arguments对象:

  • 访问参数 - arguments[index]
  • 获取参数个数 - length属性
1 function sayHi(){
2     console.log("Hello " + arguments[0] + "," + arguments[1]);
3     console.log(arguments.length);   // 输出传入的参数个数
4 }
5 
6 sayHi("wyb", "good morning!");
7 
8 // console.log() -> 在浏览器中的命令行输出

根据arguments对象实现让函数接受任意个参数并分别实现适当的功能:

 1 function add(){
 2     if (arguments.length == 1){
 3         alert(arguments[0]); 
 4     }
 5     else if (arguments.length == 2){
 6         alert(arguments[0] + arguments[1]);
 7     }
 8 }
 9 
10 add(10);         // 10
11 add(10, 20);   //  30

另外arguments对象可以和传统的命名参数一起结合使用:

 1 function add(num1, num2){
 2     if (arguments.length == 1){
 3         alert(num1); 
 4     }
 5     else if (arguments.length == 2){
 6         alert(num1 + arguments[1]);
 7     }
 8 }
 9 
10 add(10);         // 10
11 add(10, 20);   //  30

在上面这个程序中num1就相当于arguments[0],num2就相当于arguments[1],另外arguments的值始终和对应命名参数的值保持一致

注:没有传值的命名参数就被自动赋予undefined值类似变量定义时没有初始化一样;JavaScript中所有参数传递的都是值,不可能通过引用传递参数

(2)返回值

  • JavaScript中函数可以有也可以没有返回值,使用return来返回返回值
  • 函数会在return之后停止执行并立即退出,退出之后位于return之后的语句将不会执行;
  • 函数中可以多个return
  • return也可以不带任何返回值
 1 // 带返回值的函数
 2 function sum(num1, num2){
 3     return num1 + num2;
 4 }
 5 
 6 // return之后的语句不会执行
 7 function sum(num1, num2){
 8     return num1 + num2;
 9     alert("return之后的语句不会执行");    // 不会执行
10 } 11 12 // 包含多个return 13 function diff(num1, num2){ 14 if (num1 < num2) { 15 return num2 - num1; 16  } 17 else { 18 return num1 - num2; 19  } 20 } 21 22 // 不带任何返回值的return 23 function sayHi(name, message){ 24 alert("Hello " + name + ", " + message); 25 return; 26 } 27 sayHi("wyb", "Good morning!"); 

 

3.JavaScript函数注意事项

(1)JavaScript函数无重载

传统的重载:

Java和C++中的重载是可以为一个函数编写两个定义,只要这两个函数接受参数的类型和数量不同即可

JavaScript中不存在上述传统意义上的重载,但是JavaScript可以提过检查传入函数中的参数的类型和数量从而做出不同的反应,可以模拟重载,例如下面这一段:

 1 function add(){
 2     if (arguments.length == 1){
 3         alert(arguments[0]); 
 4     }
 5     else if (arguments.length == 2){
 6         alert(arguments[0] + arguments[1]); 7  } 8 } 9 10 add(10); // 10 11 add(10, 20); // 30

4.JavaScript3种基本函数

(1)普通函数

上面所有的函数均是普通函数
1 function func(arg){
2     return true;
3 }

(2)匿名函数

没有名字的函数

1 var func = function(arg){
2      return "tony";
3 }
4 
5 setInterval(function(){
6      console.log(123);
7 }, 5000)

(3)自执行函数

程序从上到下解释执行,创建函数并且自动执行

1 (function(arg){
2       console.log(arg);
3 })('123')

二、JavaScript作用域

1.JavaScript执行环境

执行环境:定义变量及函数有权访问的数据,决定它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中

某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出-例如关闭网页或浏览器时才会被销毁)

函数与执行环境:每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境

2.作用域

什么是作用域:一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域

  • C/C++/C#/Java等语言以代码块为作用域 -> 代码块以{}区分
  • python/JavaScript以函数为作用域

关于JavaScript的作用域:JavaScript中每个函数都有自己的作用域,当出现函数嵌套时,就出现了作用域链。当内层函数使用变量时,会根据作用域链从内到外一层层的循环,如果不存在,则异常

 1 public void Func(){
 2     if(1==1)
 3     {
 4         string name = "java";
 5         console.writeline(name);        // 正常运行
 6     }
 7     console.writeline(name);            // 报错
 8 } 9 10 Func()
1 def func():
2     if 1==1:
3         name = "python"
4         print(name)            // 正常运行
5     print(name)                // 正常运行
6 
7 func()
8 print(name)                    // 报错
function func(){
    if(1==1){
        var name = "javascript";
        console.log(name);                // 正常运行
    }
    console.log(name);                    // 正常运行
}

func();
console.log(name);                        // 报错

3.作用域链

当代码在一个环境中执行时,会创建变量对象的一个作用域链

作用域链的作用:保证对执行环境有权访问的所有变量和函数的有序访问

关于作用域和作用域链:

  • 函数的作用域在函数未被调用之前就已经创建
  • 函数的作用域存在作用域链,作用域链也是在函数被调用之前创建的
 1 // 函数的作用域在函数未被调用之前确定
 2 name = "wyb"
 3 function func(){
 4     var name = "xxx";
 5     function inner(){
 6         var name = "ooo";
 7         console.log(name);            // 输出: ooo
 8     }
 9 
10  inner() 11 } 12 13 func(); 14 15 16 name = "wyb" 17 function func(){ 18 var name = "xxx"; 19 function inner(){ 20 // var name = "ooo"; 21 console.log(name); // 输出: xxx 22  } 23 24  inner() 25 } 26 27 func() 28 29 30 name = "wyb" 31 function func(){ 32 // var name = "xxx"; 33 function inner(){ 34 // var name = "ooo"; 35 console.log(name); // 输出: wyb 36  } 37 38  inner() 39 } 40 41 func() 42 43 44 // 函数的作用域存在作用域链 作用域链也是在函数被调用之前创建的 45 name = "wyb" 46 function func(){ 47 var name = "xxx"; 48 function inner(){ 49 var name = "ooo"; 50 console.log(name); // 输出: ooo 51  } 52 53 return inner; 54 } 55 56 var ret = func() 57 ret() 58 59 60 name = "wyb" 61 function func(){ 62 var name = "xxx"; 63 function inner(){ 64 // var name = "ooo"; 65 console.log(name); // 输出: xxx 66  } 67 68 return inner; 69 } 70 71 var ret = func() 72 ret() 73 74 75 name = "wyb" 76 function func(){ 77 // var name = "xxx"; 78 function inner(){ 79 // var name = "ooo"; 80 console.log(name); // 输出: wyb 81  } 82 83 return inner; 84 } 85 86 var ret = func() 87 ret()

注意以下问题:

 1         name = "wyb"
 2     function func(){
 3         var name = "xxx";
 4         function inner(){
 5                 // var name = "ooo";
 6             console.log(name);            // 输出: tony
 7         }
 8         var name = "tony";
 9 
10         return inner; 11  } 12 13 var ret = func() 14 ret()

输出tony的原因是:

4.函数内局部变量会提前声明

 1 // 函数内部局部变量会提前声明
 2 // 当解释程序时,在函数提前生成作用域链的同时找到内部所有的局部变量
 3 // 然后提前声明变量  var xxoo;  // 此时输出xxoo的值为undefined
 4 
 5 function func(){
 6     console.log(xxoo);
 7 }
 8 
 9 func()        // 程序直接报错
10 
11 
12 function func(){
13     console.log(xxoo);
14     var xxoo = "666"; 15 } 16 17 func() // undefined

猜你喜欢

转载自www.cnblogs.com/wyb666/p/9326768.html