函数与作用域

作者: 饥人谷_Jack | 来源:发表于2017-10-02 14:06 被阅读0次

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

    • 使用函数声明,如果函数被提前调用也是可以正常运行的;如果使用函数表达式,和变量提升是一样的,提前调用会返回undefined。

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

    • 变量声明前置
      • JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到当前作用域的头部,这就叫做变量的声明前置,也叫变量提升(hoisting)。
    console.log(a) //undefined
    var a = 1;
    console.log(a); //1
    //相当于
    var a;
    console.log(a);
    a = 1;
    console.log(a);
    
    • 函数声明前置
      • 和变量的声明会前置一样,函数声明同样会前置,如果我们使用函数表达式那么规则和变量一样。如果我们使用函数声明的方式,那么即使函数写在最后也可以在前面语句调用,前提是函数声明部分已经被下载到本地
    fn();
    function fn() {
        console.log(3);
    }
    

    3. arguments 是什么

    • arguments 是函数内置的一个对象,可以返回传递参数,也就是实参。

    4. 函数的"重载"怎样实现

    • 函数名+参数列表,也就是说相同名字的函数参数个数不同或者顺序不同都被认为是不同的函数,称为函数重载,javascript没有重载的概念,但是可以使用其他方式通过重载使用一个函数参数不同的功能。
    function fn(name,age,sex) {
    
     if (name) {
     console.log(name);
    }
    if (age) {
     console.log(age);
    }
    if (sex){
     console.log(sex);
    }
    }
    fn('luoqian');
    fn('luoqian',21);
    fn('luoqian',21,'female');
    

    5. 立即执行函数表达式是什么?有什么作用

    • (function(){}) (),这样可以隔离作用域,避免无染全局作用域。

    6. 求n!,用递归来实现

     function factorial(n) {
                if(n==0) {
                    return 1;
                }
                if(n==1) {
                    return 1;
                } 
                return n*factorial(n-1);
                console.log(n*factorial(n-1));
            }
    

    7. 以下代码输出什么?

    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('饥人谷', 2, '男');//'name:',饥人谷    'age:', 2    'sex:', 男   ['饥人谷', 2, '男']    'name:',valley
        getInfo('小谷', 3);//'name:',小谷    'age:', 3    undefined    ['小谷', 3]   'name:',valley
        getInfo('男');//'name:',男    undefined    undefined    ['男']     'name:',valley
    

    8. 写一个函数,返回参数的平方和?

      function sumOfSquares(n){
          var sum=0;
          for(var i=0;i<arguments.length;i++) {
            sum+=arguments[i]*arguments[i]
          }
          return sum;
        }
        var result = sumOfSquares(2,3,4)
        var result2 = sumOfSquares(1,3)
        console.log(result)  //29
        console.log(result2)//10
    

    9. . 如下代码的输出?为什么?

        console.log(a);//输出undefined,因为变量声明提升
        var a = 1;
        console.log(b);//报错,b未被声明
    

    10. 如下代码的输出?为什么

        sayName('world');//输出hello world,函数声明提升。
        sayAge(10);//报错,函数表达式声明函数相当于变量声明,只是先声明,还没有被赋值,所以使用函数形式条用会报错。
        function sayName(name){
            console.log('hello ', name);
        }
        var sayAge = function(age){
            console.log(age);
        };
    

    11. 如下代码输出什么? 写出作用域链查找过程伪代码

    var x = 10
    bar() 
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
      foo()
    }//输出10
    /*
            globalContext = {
                AO:{
                    x:10,
                    foo:function,
                    bar:function
                }
            }
            foo[[scope]]=globalContext.AO;
            bar[[scope]]=globalContext.AO;
            
            barContext = {
                AO: {
                    x:30,
                }
                scope:globalContext.AO;
            }
    */
    

    12. 如下代码输出什么? 写出作用域链查找过程伪代码

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x) 
      }
      foo();
    }   //输出30
    /*
            globalContext = {
                AO:{
                    x:10,
                    bar:function
                }
            }
            bar[[scope]]=globalContext.AO;
            
            barContext = {
                AO: {
                    x:30,
                    foo:function
                }
                scope:globalContext.AO;
            }
            foo[[scope]]=barContext.AO
     */ 
    

    13. 以下代码输出什么? 写出作用域链的查找过程伪代码

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      (function (){
        console.log(x)
      })()
    }//输出30
            /*
            globalContext = {
                AO:{
                    x:10,
                    bar:function
                }
            }
            bar[[scope]]=globalContext.AO;
            
            barContext = {
                AO: {
                    x:30,
                    function
                }
                scope:globalContext.AO;
            }
            function[[scope]]=barContext.AO
            */ 
    

    14. 以下代码输出什么? 写出作用域链查找过程伪代码

    var a = 1;
    
    function fn(){
      console.log(a)
      var a = 5
      console.log(a)
      a++
      var a
      fn3()
      fn2()
      console.log(a)
    
      function fn2(){
        console.log(a)
        a = 20
      }
    }
    
    function fn3(){
      console.log(a)
      a = 200
    }
    
    fn()
    console.log(a) //输出 undefined 5 1 6 20 200
            /*
            globalContext = {
                AO:{
                    a:200,
                    fn:function,
                    fn3:function
                }
            }
            fn[[scope]]=globalContext.AO;
            fn3[[scope]]=globalContext.AO;
            
            fnContext = {
                AO: {
                    a:20,
                    fn2:function
                }
                scope:globalContext.AO;
            }
            fn2[[scope]]=fnContext.AO
            
            fn3Context = {
                AO:{}
                scope:globalContext.AO;
            }
    
            fn2Context = {
                AO:{}
                scope:fnContext.AO;
            }
            
            //undefined 5 1 6 20 200
            */ 
    

    相关文章

      网友评论

        本文标题:函数与作用域

        本文链接:https://www.haomeiwen.com/subject/tfzzextx.html