美文网首页
JS(二)--函数与作用域链

JS(二)--函数与作用域链

作者: Gia_Mo | 来源:发表于2017-03-21 20:14 被阅读0次
    1.函数声明和函数表达式有什么区别

    函数声明:function functionName(){}
    函数表达式:var fn = function(){}
    函数声明会提前,函数表达式可以省略函数名。

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

    所谓的变量声明前置就是在一个作用域块中,所有的变量都被放在块的开始出声明。和变量声明前置一样,执行代码之前会先读取函数声明,只要函数在代码中进行了声明,无论它在哪个位置上进行声明,js引擎都会将它的声明放在范围作用域的顶部。

    3.arguments 是什么

    arguments是一个类数组对象,代表传给一个function的参数列表,可以在函数内部通过使用 arguments 对象来获取函数的所有参数。

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

    在JS中,没有重载。同名函数会覆盖。但可以在函数体针对不同的参数调用执行相应的逻辑。

    5.立即执行函数表达式是什么?有什么作用
    (function(){})()
    // 作用是隔离作用域
    
    6.求n!,用递归来实现
    function recursive(n){
        if (n === 1) {
            return 1
        }
        return n*recursive(n-1)
    }
    console.log(recursive(4)); //24
    
    7.以下代码输出什么?
    function getInfo(name, age, sex){
        console.log('name:',name); // name: 饥人谷/name: 小谷/name: 男
        console.log('age:', age);  // age: 2/age: 3/age: undefined
        console.log('sex:', sex);  // sex: 男/sex: undefined/sex: undefined
        console.log(arguments);    // ['饥人谷',2,'男']/['小谷',3]/['男']
        arguments[0] = 'valley';
        console.log('name', name);  // name valley/name valley/name valley
    }
    
    getInfo('饥人谷', 2, '男'); 
    getInfo('小谷', 3);
    getInfo('男');
    
    8.写一个函数,返回参数的平方和
    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
    
    9.如下代码的输出?为什么
    console.log(a); //undefined
    var a = 1;
    console.log(b); //报错:b is not defined
    /* 由于声明前置,所以在输出a这条语句执行之前已经声明了a变量,而b变量并没有声明*/
    
    10.如下代码的输出?为什么
    sayName('world');  // hello world
    sayAge(10);        // 报错: sayAge is not a function
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
    /*由于sayName是用函数声明的方式,因此声明提前;而sayAge是采用函数表达式的方式*/
    
    11.如下代码输出什么? 写出作用域链查找过程伪代码
    var x = 10
    bar() 
    function foo() {
      console.log(x)  // 10
    }
    function bar(){
      var x = 30
      foo()
    }
    /*
    1. globalContext = {
        Ao:{
          x: 10,
          foo: function(){},
          bar: function(){}
        },
        Scope: null
    }
    //声明foo和bar时
       foo.[[scope]] = globalContext.Ao
       bar..[[scope]] = globalContext.Ao
    2. barContext = {
        Ao:{
          x:30,
          foo: function(){}
        },
        Scope: globalContext.Ao
    }
    3. fooContext = {
        Ao:{
        },
        Scope: globalContext.Ao
    }
    */
    
    12.如下代码输出什么? 写出作用域链查找过程伪代码
    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x)  // 30
      }
      foo();
    }
    /*
    1. globalContext = {
        Ao:{
          x: 10,
          bar: function(){}
        },
        Scope: null
    }
    //声明bar时
       foo.[[scope]] = globalContext.Ao
    2. barContext = {
        Ao:{
          x:30,
          foo: function(){}
        },
        Scope: globalContext.Ao
    }
    //声明foo时
       foo.[[scope]] = barContext.Ao
    3. fooContext = {
        Ao:{
        },
        Scope: barContext.Ao
    }
    */
    
    13.如下代码输出什么? 写出作用域链查找过程伪代码
    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      (function (){
        console.log(x) // 30
      })()
    }
    /*
    1. globalContext = {
        Ao:{
          x: 10,
          bar: function(){}
        },
        Scope: null
    }
    //声明bar时
       foo.[[scope]] = globalContext.Ao
    2. barContext = {
        Ao:{
          x:30,
          匿名函数:function(){}
        },
        Scope: globalContext.Ao
    }
    3. 匿名函数的Context = {
        Ao:{
        },
        Scope: barContext.Ao
    }
    */
    
    14.如下代码输出什么? 写出作用域链查找过程伪代码
    var a = 1;
    
    function fn(){
      console.log(a)  //undefined
      var a = 5
      console.log(a)  // 5
      a++
      var a
      fn3()
      fn2()
      console.log(a)  // 20
    
      function fn2(){
        console.log(a)  // 6
        a = 20
      }
    }
    
    function fn3(){
      console.log(a)  // 1
      a = 200
    }
    
    fn()
    console.log(a)  // 200
    /*
    1. globalContext = {
        Ao:{
          a: 200,
          fn: function(){},
          fn3: function(){}
        },
        Scope: null
    }
    声明fn/fn3时
       fn.[[scope]] = globalContext.Ao
       fn3.[[scope]] = globalContext.Ao
    2. 执行fn
      fnContext = {
        Ao:{
          a:20,
          fn2:function(){}
        },
        Scope: globalContext.Ao
    }
    声明fn2时
       fn2.[[scope]] = fnContext.Ao
    3. 执行fn3
      fn3Context = {
        Ao:{
        },
        Scope: globalContext.Ao
    }
    4. 执行fn2
       fn2Context = {
        Ao:{ 
        },
        Scope: fnContext.Ao
       }
    */
    

    相关文章

      网友评论

          本文标题:JS(二)--函数与作用域链

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