美文网首页
函数与作用域

函数与作用域

作者: 无目的 | 来源:发表于2017-06-22 12:48 被阅读0次

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

    声明函数:ECMAScript规定了三种声明函数方式

    • 构造函数
      首先函数也是对象的一种,我们可以通过其构造函数,使用new来创建一个 函数对象
      var sayHello = new Function("console.log('hello world');");//不推荐使用
    
    • 函数声明
      使用function关键字可以声明一个函数
     //函数声明
      function sayHello(){
        console.log('hello')
      }
    
      //函数调用
      sayHello()
    //声明不必放到调用的前面
    
    • 函数表达式
      var sayHello = function(){
        console.log('hello');
      }
    
      sayHello()
    //声明必须放到调用的前面
    

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

    • 在一个作用域下,var 声明的变量和function 声明的函数会前置
    console.log(a); //undefined
    var a = 3;
    console.log(a); //3
    
    sayHello();
    
    function sayHello(){
      console.log('hello');
    }
    
    • 函数内部的声明前置
    function fn(){
      console.log(a)  //undefined
      var a = 3
      console.log(a)
    }
    fn()
    

    arguments 是什么

    函数的"重载"怎样实现

    在 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');
    

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

    • 立即执行函数表达式
    (function(){
      var a  = 1;
    })()
    console.log(a); //undefined
    
    • 作用: 隔离作用域

    求n!,用递归来实现

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

    以下代码输出什么?

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

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

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

    如下代码的输出?为什么

        console.log(a);//undefined
        var a = 1;
        console.log(b);// b is not defined
    /*
    此代码执行顺序为:
    var a -> console.log(a) 结果为 undefined
    -> a = 1 -> console.log(b) 报错,"b"  未定义 
    */
    

    如下代码的输出?为什么

        sayName('world');
        sayAge(10);
        function sayName(name){
            console.log('hello ', name);
        }//hello  world
        var sayAge = function(age){
            console.log(age);
        };/*sayAge is not a function:var sayAge 变量声明前置,
    但只会声明此变量不会将其赋值为函数,所以函数 sayAge 的调用必须在函数赋值之后,否则会报错。*/
    

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

    var x = 10
    bar() 
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
      foo()
    }
    
    /*globalContext = {
      AO: {
        x: 10
        foo: function
        bar: function
      },
      Scope: null
    }
    
    //声明 foo 时 得到下面
    foo.[[scope]] = globalContext.AO
    //声明 bar 时 得到下面
    bar.[[scope]] = globalContext.AO
    
    当调用 bar() 时, 进入 bar 的执行上下文
    
    barContext = {
      AO: {
        x: 30
      },
      Scope: bar.[[scope]] //globalContext.AO
    }
    当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找不到再从 bar 的 [[scope]]里找
    
    找到后即调用
    当调用 foo() 时,进入 foo 的执行上下文
    
    fooContext = {
      AO: {},
      Scope: foo.[[scope]] // globalContext.AO
    }
    
    所以 console.log(x)是 10
    */
    

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

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x) 
      }
      foo();
    }   
    /*globalContext = {
      AO: {
        x: 10
        bar: function
      },
      Scope: null
    }
    
    //声明 bar 时 得到下面
    bar.[[scope]] = globalContext.AO
    
    注意: 在当前的执行上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的 AO
    
    当调用 bar() 时, 进入 bar 的执行上下文
    
    barContext = {
      AO: {
        x: 30,
        foo: function
      },
      Scope: bar.[[scope]] //globalContext.AO
    }
    //在 bar 的执行上下文里声明 foo 时 得到下面
    foo.[[scope]] = barContext.AO
    当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找到后即调用
    
    笔试题
    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); 
    
    当调用 bar() 时, 进入 bar 的执行上下文
    
    barContext = {
      AO: {
        x: 30,
        foo: function
      },
      Scope: bar.[[scope]] //globalContext.AO
    }
    //在 bar 的执行上下文里声明 foo 时 得到下面
    foo.[[scope]] = barContext.AO
    
    当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找到后即调用
    
    当调用 foo() 时,进入 foo 的执行上下文
    
    fooContext = {
      AO: {},
      Scope: foo.[[scope]] // barContext.AO
    }
    
    所以 console.log(x)是 30
    */
    

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

    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      (function (){
        console.log(x)
      })()
    }
    
    /*
    (function (){
        console.log(x)
      })()等同于
    var f =function (){
    }f();
    
    globalContext = {
    AO: {
        x: 10;
        bar: function       
    }
    bar.[[scope]] = globalContext.AO
    }
    
    barContext = {
    AO: {
        x: 30
        function()
    },
    function.[[scope]] = barContext.AO
    Scope: globalContext.AO
    }
    
    functionContext = {
    AO: {},
    Scope: barContext.AO
    }
    barContext.AO{x = 30}
    输出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)
    
    /*
    globalContext = {
    AO: {
        a:200;
        fn: function
       fn3 :function      
    }
    
    }
    fn.[[scope]] = globalContext.AO
    fn3.[[scope]] = globalContext.AO
    fnContext = {
    AO: {
        a: 20
    },
    scope:globalContext.AO
    }
    fn2.[[scope]] =fnlContext.AO
    
    fn3Context = {
    AO: {
        a: 20
        fn2:function(){}
    },
    scope:globalContext.AO
    }
    
    fn2Context = {
    AO: {
        a: 
        fn2:function(){}
    },
    scope:globalContext.AO
    }
    //undefined 5 1 6 20 200
    */
    

    相关文章

      网友评论

          本文标题:函数与作用域

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