美文网首页
进阶-函数与作用域

进阶-函数与作用域

作者: 荣_Rong | 来源:发表于2017-05-03 19:54 被阅读0次

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

     //函数声明
      function sayHello(){
        console.log('hello')
      }
    
    //函数表达式
     var sayHello = function(){
        console.log('hello');
      }
    
    • 函数声明在JS解析时进行函数前置,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。
    • 函数表达式的值是在JS运行时确定,并且在表达式赋值完成后,该函数才能调用。

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

    变量的声明前置:JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被前置到代码的头部。

    console.log(a);                            
    var a = 1;
    
    //声明前置
    var a;
    console.log(a);
    a = 1;    //undefined
    

    函数声明前置:JavaScript引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被前置到代码头部。

    3. arguments 是什么

    Arguments是一个类似数组但不是数组的对象,除了长度之外没有任何数组属性。
    在函数内部,你可以使用arguments对象获取到该函数的所有传入参数。

      function printPersonInfo(name, age, sex){
        console.log(name);
        console.log(age);
        console.log(sex);
        console.log(arguments);
      }
    

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

    Js 不支持函数的重载,可以用相同的名字在同一作用区域,定义两个函数,但后面一个会覆盖前面,但可以在函数体针对不同的参数调用执行相应的逻辑

    function printPeopleInfo(name, age, sex){
      if(name){
        console.log(name);
      }
      if(age){
        console.log(age);
      }
      if(sex){
        console.log(sex);
      }
    }
    
    
    printPeopleInfo('Byron', 26);
    printPeopleInfo('Byron', 26, 'male');
    

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

    立即执行函数需要把函数声明和调用函数写一起,不过直接放一起会起冲突,需要用()包围声明的函数。

    (function(){
      var a  = 1;
    })()
    
    console.log(a); //undefined
    

    作用是:隔离作用域。

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

    function fate (n) {
        if (n===1){
            return 1
        }
        return n*fate(n-1)
    }
    

    7. 以下代码输出什么?

    name : 饥人谷
    age : 2
    sex : 男
    [name:饥人谷, age:2,sex:男] 
    name valley
    name:小谷
    age:3
    sex:undefined
    [name:小谷,age:2,sex:undefined]
    name valley
    name:男
    age:undefined
    sex:undefined
    [name:男,age:undefined,sex:undefined]
    name valley
    

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

    
    
    
    function sumOfSquares(){
        var sum=0;
        for (var i=0;i< arguments.length;i++){
            sum+=arguments[i]*arguments[i];
        }
        return sum;
    }
    
    

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

        console.log(a);       //undefined
        var a = 1;
        console.log(b);       //b is not defined
    
    
    a声明前置。b没有声明对象
        var a
            console.log(a);
            a = 1;
        console.log(b);
    

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

        sayName('world');
        sayAge(10);
        function sayName(name){
            console.log('hello ', name);
        }
        var sayAge = function(age){
            console.log(age);
        };
    //hello world        声明前置
    //sayAge is not a function()           使用函数表达式应先定义后调用 
    

    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
      }
      Scope: null
    }
    foo.[[scope]] = globalContext.AO
    bar.[[scope]] = globalContext.AO
    
    调用bar()
    barContext = {
      AO: {
        x: 30
      }
      Scope: bar.[[scope]] = globalContext.AO
    }
    
    调用foo()
    fooContext = {
      AO: {}
      Scope: foo.[[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
      }
      Scope: null
    }
    bar.[[scope]] = globalContext.AO
    
    调用bar()
    barContext = {
      AO: {
        x: 30
        foo: function
      }
      Scope: bar.[[scope]] = globalContext.AO
    }
    foo.[[scope]] = barContext.AO
    
    调用foo()
    fooContext = {
      AO: {}
      Scope: 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
      }
      Scope: null
    }
    bar.[[scope]] = globalContext.AO
    
    调用bar()
    barContext = {
      AO: {
        x: 30
        function(){}
      }
      Scope: bar.[[scope]] = globalContext.AO
    }
    function.[[scope]] = barContext.AO
    
    调用function()
    functionContext = {
      AO: {}
      Scope: 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 6 1 20 200
    
    
    globalContext = {
      AO: {
        a: 1 ==>a: 200
        fn: function
        fn3: function
      }
      Scope: null
    }
    fn.[[scope]] = globalContext.AO
    fn3.[[scope]] = globalContext.AO
    
    调用fn()
    fnContext = {
      AO: {
        a: undefined(输出:undefined)==>5(输出:5)==>6
        fn2: function
      }
      Scope: fn.[[scope]] = globalContext.AO
    }
    fn2.[[scope]] = fnContext.AO
    
    调用fn3()
    fn3Context = {
      AO: {}
      Scope: fn3.[[scope]] = globalContext.AO
    }输出:1
    
    调用fn2()
    fn2Context = {
      AO: {}输出:6 ==>a: 20(输出:20)
      Scope: fn2.[[scope]] = fnContext.AO
    }
    
    console.log(a) 输出:200 
    

    相关文章

      网友评论

          本文标题:进阶-函数与作用域

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