美文网首页
函数与作用域

函数与作用域

作者: 柚丶稚橙熟时 | 来源:发表于2017-05-17 23:30 被阅读0次

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

    函数声明
    function fn() {}
    fn();
    1 函数声明必须有函数名
    2 函数可以在任意地方调用fn();

    函数表达式
    var fn = function fn () {};
    1 前后两个函数的名字可以相同也可以不相同
    2 function 后面的这个名字是可以省略的
    3 function 后面的这个名字只能再函数内部使用
    4 函数调用只有在函数表达式声明后调用。

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

    在一个作用域下,var 声明的变量和function 声明的函数会前置。
    变量的声明前置,var声明的变量按顺序提升到当前作用域最前,赋值为undefined
    函数的声明前置,function声明的函数和变量一样前置,且都按照顺序提升。

    arguments 是什么

    在JavaScript中,arguments是对象的一个特殊属性。arguments对象就像数组,但是它却不是数组。
    1:arguments是收到的实参副本
    在词法分析中, 首先按形参形成AO的属性,值为undefined
    当实参传来时, 再修改AO的相应属性.  
    2:并把所有收到实参收集起来,放到一个arguments对象里  
    t(a,b,c){},  
    调用时: t(1,2,3,4,5) 5个参数  
    此时 , AO属性只有a,b,c,3个属性, arguments里有1,2,3,4,5, 所有的值

    函数的"重载"怎样实现

    function fn(hehe,haha,xixi){
      if(arguments.length==1){
        .....
      }
      if(arguments.length==2){
        .....
      }
      if(arguments.length==3){
        .....
      }
    }
    

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

    立即执行函数表达式,首先它是一个表达式,而不是一个声明函数。其次,因为是表达式,所以可以用(), +, !, -等运算符来触发。
    例如:(function(){…})()
    函数会立即执行,并且可以隔离作用域,立即执行函数内的任何赋值都不会影响这个函数外的变量和函数。

    求n!,用递归来实现

    function fn(n){
        if(n<=1){
            return 1;
        }
        return n*fn(n-1);
    }
    

    以下代码输出什么?

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

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

    function sumOfSquares(){
        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
    

    如下代码的输出?为什么

        console.log(a);
        var a = 1;
        console.log(b);
    变量提升后:
        var a;
        console.log(a);
        a = 1;
        console.log(b);
    输出:
    undefined   /   b is not defined
    

    如下代码的输出?为什么

        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
    函数表达式不会前置,所以执行sayAge(10);  sayAge还不是一个函数。
    

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

    var x = 10
    bar() 
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
      foo()
    }
    

    输出10

    gContext={
        AO:{
            x:10,
            foo:function(){},
            bar:function(){},
        },
        scope:null
    }
    foo[[scope]]=gContext.AO;//声明 foo 时 得到
    bar[[scope]]=gContext.AO;//声明 bar 时 得到
    barContext={//当调用 bar() 时, 进入 bar 的执行上下文
        AO:{
            x:30
        },
        scope:gContext.AO
    }
    fooContext={//当调用 foo() 时, 进入 foo 的执行上下文
        AO:{
        },
        scope:gContext.AO
    }//console.log(x)开始找x,最终在gContext.AO里找到x 即10
    
    

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

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x) 
      }
      foo();
    }   
    

    输出30

    gContext={
        AO:{
            x:10,
            bar:function(){},
        },
        scope:null
    }
    
    bar[[scope]]=gContext.AO;//声明 bar 时 得到
    barContext={//当调用 bar() 时, 进入 bar 的执行上下文
        AO:{
            x:30
            foo:function(){},
        },
        scope:gContext.AO
    }
    foo[[scope]]=barContext.AO;//声明 foo 时 得到
    fooContext={//当调用 foo() 时, 进入 foo 的执行上下文
        AO:{
        },
        scope:barContext.AO
    }//console.log(x)开始找x,最终在barContext.AO里找到x 即30
    
    

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

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      (function (){
        console.log(x)
      })()
    }
    

    输出30

    gContext={
        AO:{
            x:10,
            bar:function(){},
        },
        scope:null
    }
    
    bar[[scope]]=gContext.AO;//声明 bar 时 得到
    barContext={//当调用 bar() 时, 进入 bar 的执行上下文
        AO:{
            x:30
            noname:function(){},
        },
        scope:gContext.AO
    }
    noname[[scope]]=barContext.AO;//声明 匿名函数 时 得到
    fooContext={//当调用 匿名函数 时, 进入 匿名函数 的执行上下文
        AO:{
        },
        scope:barContext.AO
    }//console.log(x)开始找x,最终在barContext.AO里找到x 即30
    
    

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

    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)
    

    变量提升后如下:

    var a ;
    
    function fn(){
      var a;
      function fn2(){
        console.log(a)
        a = 20
      }
      console.log(a)
      a = 5
      console.log(a)
      a++
      fn3()
      fn2()
      console.log(a)
    }
    
    function fn3(){
      console.log(a)
      a = 200
    }
    a = 1
    fn()
    console.log(a)
    

    输出 undefined 5 1 6 20 200. 作用域链查找过程伪代码完整如下

    gContext={
        AO:{
            a:undefined,
            fn1:function(){},
            fn3:function(){},
        },
        scope:null
    }
    fn[[scope]]=gContext.AO;//声明 fn 时 得到
    fn3[[scope]]=gContext.AO;//声明 fn3 时 得到
    gContext.AO.a=1;
    
    fnContext={//当调用 fn() 时, 进入 fn 的执行上下文
        AO:{
            a:undefined;
            fn2:function(){},
        },
        scope:gContext.AO
    }
    fn2[[scope]]=fnContext.AO;//声明 fn2 时 得到
    //console.log(x)开始找x,最终在fnContext.AO里找到x 即undefined
    fnContext.AO.a = 5;
    //console.log(x)开始找x,最终在fnContext.AO里找到x 即5
    fnContext.AO.a++;
    
    fn3Context={//当调用 fn3 时, 进入 fn3 的执行上下文
        AO:{
        },
        scope:gContext.AO
    }
    //console.log(x)开始找x,最终在gContext.AO里找到x 即1
    gContext.AO.a=200;
    
    fn2Context={//当调用 fn2() 时, 进入 fn2 的执行上下文
        AO:{
        },
        scope:fnContext.AO
    }
    //console.log(x)开始找x,最终在fnContext.AO里找到x 即6
    fnContext.AO.a=20;
    
    fnContext={//当调用 fn() 时, 进入 fn 的执行上下文
        AO:{
            a:20;
            fn2:function(){},
        },
        scope:gContext.AO
    }
    //console.log(x)开始找x,最终在fnContext.AO里找到x 即20
    gContext={//当fn()调用结束时,回到全局上下文
        AO:{
            a:200;
            fn2:function(){},
        },
        scope:null
    }
    //console.log(x)开始找x,最终在gContext.AO里找到x 即200
    

    相关文章

      网友评论

          本文标题:函数与作用域

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