饥人谷技术博客

JS——函数

2016-08-18  本文已影响112人  进击的阿群

1. 函数声明和函数表达式有什么区别 (*)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      var test1 = function say() {
        console.log('hello world');
      };              //  函数表达式,有分号,是语句
      test1();        //  hello world
      sayName();      //  大阿群
      say();          //  error
      function sayName() {
        console.log('大阿群');
      }               //  函数声明,无分号
    </script>
  </body>
</html>
函数声明&函数表达式

参考[翻译]函数:声明和表达式


2. 什么是变量的声明前置?什么是函数的声明前置 (**)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      console.log(a);    // undefined
      var a = 1;
      demo();
      console.log(a);    // 2
      function demo() {
        a = 2;
      }
      console.log(b);    // error
    </script>
  </body>
</html>
声明前置
可以看出,未定义的b会出现错误,而a变量声明前置,但是执行第一个console.log的时候a未初始化,所以值未undefined,继续往下执行demo()函数,虽然demo()函数声明是在执行之后,但是由于函数声明前置,所以正确执行显示2。

3. arguments 是什么 (*)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      Array.prototype.testArg = "test";
      function funcArg() {
        console.log(funcArg.arguments[0]);
        console.log(funcArg.arguments.testArg);
      }
      console.log(new Array().testArg);
      funcArg(1,2);
    </script>
  </body>
</html>
arguments类似数组,但不是数组实例
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      function f(a, b, c) {
        console.log(arguments.length); // 2
        console.log(a);                // 1
        a = 100 ;
        console.log(a);                // 100
        console.log(arguments[0]);     // 100
        console.log(c);                // undefined
        c = 200;
        console.log(arguments[2]);     // undefined
      }
      f(1,2);
    </script>
  </body>
</html>
arguments为实参

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>task17</title>
</head>
<body>
<script>
function f(a) {
return a + 10;
}
function f(a) {
return a - 10;
}
console.log(f(1));
</script>
</body>
</html>

![JS函数不能重载](http://i2.buimg.com/567571/d9005d24b2e63f63.png)
* arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。
``` html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      function count(a) {
        if(a == 1) {
          return 1;
        }
        return a + arguments.callee(--a);
      }
      var mm = count(10);
      console.log(mm);
    </script>
  </body>
</html>
arguments.callee

不过call属性在严格模式下被禁用了,这点需要注意。

参考arguments对象


4. 函数的重载怎样实现 (**)

在一些编程语言中,函数的返回值类型和参考不同会使得同一个函数有不同的功能一同实现,这是函数重载;而在Javascript中没有重载的概念,所以正常情况下的函数是无法重载的:


JS无重载概念

不过可以用arguments属性来判断实参的个数,模拟重载:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>task17</title>
  </head>
  <body>
    <script>
      function test() {
        if(arguments.length == 1) {
          console.log(arguments[0] + 3);
        } else if(arguments.length == 2) {
          console.log(arguments[0] * arguments[1]);
        }
      }

      test(1, 2);
    </script>
  </body>
</html>
未声明局部变量
  • 所有window对象的属性拥有全局作用域
  • 局部作用域(Local Scope)
     和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域:
    局部作用域
  • 作用域链
    作用域链是内部上下文所有变量对象(包括父变量对象)的列表,用来变量查询。在代码执行的过程中,所用到的变量会在当前作用域中进行寻找,如果找不到,就会往沿着作用域链向上一级进行寻找,一直到全局作用域为止,如果找到便会停止(而不理会上一级是否有同名的变量),如果找不到,就会报错。
  •     function add(num1,num2) {
            var sum = num1 + num2;
            return sum;
        }
    

    在函数add创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图所示(注意:图片只例举了全部变量中的一部分):



    执行代码:

    var total = add(5, 10);
    

    首先在本身内部作用域中寻找所需对象,当不存在时,像外层找,执行过程中按照从上到下顺序执行,执行一层就会类似于编锁链上的一节,将其保留下来,在其生命周期内反复被查找。

    参考
    JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
    深入理解JavaScript系列(14):作用域链(Scope Chain)


    代码:

    1. 以下代码输出什么? (难度**)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-1</title>
      </head>
      <body>
        <script>
          function getInfo(name, age, sex) {
            console.log('name:',name);
            console.log('age:',age);
            console.log('sex:',sex);
            console.log(arguments);
            arguments[0] = 'valley';
            console.log('name',name);
          }
          getInfo('hunger', 28, '男');
          getInfo('hunger', 28);
          getInfo('男');
        </script>
      </body>
    </html>
    
    代码2

    3. 如下代码的输出?为什么 (难度*)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-3</title>
      </head>
      <body>
        <script>
          console.log(a);
          var a = 1;
          console.log(b);
        </script>
      </body>
    </html>
    
    代码3

    4. 如下代码的输出?为什么 (难度*)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-4</title>
      </head>
      <body>
        <script>
          sayName('world');
          sayAge(10);
          function sayName(name){
            console.log('hello', name);
          }
          var sayAge = function(age){
            console.log(age);
          };
        </script>
      </body>
    </html>
    
    代码4

    5. 如下代码的输出?为什么 (难度**)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-5</title>
      </head>
      <body>
        <script>
          function fn(){}
          var fn = 3;
          console.log(fn);
        </script>
      </body>
    </html>
    
    代码6

    按照执行顺序重写函数:

        <script>
          function fn(fn2){
            var fn2;
            function fn2(){
              console.log('fnnn2');
            }
            console.log(fn2);
            fn2 = 3;
            console.log(fn2);
            console.log(fn);
          }
          fn(10);
        </script>
    

    7. 如下代码的输出?为什么 (难度***)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-7</title>
      </head>
      <body>
        <script>
          var fn = 1;
          function fn(fn){
            console.log(fn);
          }
          console.log(fn(fn));
        </script>
      </body>
    </html>
    
    代码7

    执行顺序:

        <script>
          var fn;
          function fn(fn){
            console.log(fn);
          }
          fn = 1;
          console.log(fn(fn));
        </script>
    

    fn = 1为最终结果,无法进行()操作,所以显示错误。


    8. 如下代码的输出?为什么 (难度**)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-8</title>
      </head>
      <body>
        <script>
          console.log(j);
          console.log(i);
          for(var i = 0; i < 10; i++){
            var j = 100;
          }
          console.log(i);
          console.log(j);
        </script>
      </body>
    </html>
    
    代码8

    for是循环语句,不是函数,首先并不会前置,其次其定义的自然就是全局变量,所以能够被解析,正常顺序执行并显示。


    9. 如下代码的输出?为什么 (难度****)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-9</title>
      </head>
      <body>
        <script>
          fn();
          var i = 10;
          var fn = 20;
          console.log(i);
          function fn(){
            console.log(i);
            var i = 99;
            fn2();
            console.log(i);
            function fn2(){
              i = 100;
            }
          }
        </script>
      </body>
    </html>
    
    代码9

    执行顺序:

        <script>
          var i, fn;
          function fn(){
            var i;
            function fn2(){
              i = 100;
            }
            console.log(i);
            i = 99;
            fn2();
            console.log(i);
          }
          fn();
          i = 10;
          fn = 20;
          console.log(i);
        </script>
    

    10. 如下代码的输出?为什么 (难度*****)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>task17-10</title>
      </head>
      <body>
        <script>
          var say = 0;
          (function say(n){
            console.log(n);
            if(n < 3) return;
            say(n - 1);
          }(10));
          console.log(say);
        </script>
      </body>
    </html>
    
    代码10代码10

    本文版权归本人和饥人谷所有,转载请注明来源,谢谢

    上一篇 下一篇

    猜你喜欢

    热点阅读