美文网首页
函数与作用域

函数与作用域

作者: 虚玩玩TT | 来源:发表于2017-05-08 22:05 被阅读0次

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

    • 函数声明,使用"function"关键字声明;函数表达式,使用"var 函数名=function(){}"
    • 函数表达式必须要放到调用之前,而函数声明不需要,即函数声明会前置。

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

    代码运行的时候,在同一个作用域下,对于var声明的变量和function声明的函数会被前置声明,值为undefined,然后再逐行运行代码。

    函数有作用域,在函数内部,也会出现声明前置。

    arguments是什么?

    在函数内部,可以使用arguments获取到该函数的所有传入参数,并以对象的形式展示。例:


    task3.png

    函数的重载怎样实现?

    在js中没有重载,对重名函数,重新声明会发生覆盖。但是,可以在函数内部针对不同的参数调用不同的逻辑。例:


    task3-1.png
    task3-2.png

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

    使用括号,JS会将函数声明变成函数表达式,并会立刻执行
    还可以通过对函数添加一些运算符,使之变成表达式立刻执行。
    函数是一个作用域,在函数内部进行的设置不会对全局变量造成影响。

    (function test(){})
    (function test(){})()    /*直接加括号*/
    [function test(){}]()    /*变成数组*/
    {function test(){}}()    /*变成对象*/
    1,function test(){}()    /*使用逗号*/
    !function test(){}()    /*使用!*/
    
    

    求 n!,用递归来实现

    function f(n){
      if(n === 1) {return 1};
      return n*f(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, '男');
    getInfo('小谷', 3);
    getInfo('男');
    

    结果:

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

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

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

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

    console.log(a);  //1
    var a = 1;
    console.log(b);  //报错
    

    声明前置,a被声明,且为1,console.log(a)输出1;
    b没有声明,会报错,b is not defined

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

    sayName('world');  //hello world
    sayAge(10);  //报错
    function sayName(name){
    console.log('hello',name);
    }
    var sayAge = function(age){
    console.log(age);
    }
    

    函数声明会有声明前置,所以sayName()是被声明的;
    函数表达式没有声明前置,在执行sayAge()时,函数没有被声明,所以会报错。sayAge is not a function

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

    var x = 10
    bar()
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
    foo()
    }
    
    1
    globalContext = {
     AO: { 
      x: 10
      foo: function
      bar: function
      }
    }
    foo.[[scope]] = globalContext.AO
    bar.[[scope]] = globalContext.AO
    
    2
    barContext = {
      AO: {
        x: 30
        }
      scope: bar.[[scope]] = globalContext.AO
    }
    
    3
    fooContext = {
      AO: {}
      scope: foo.[[scope]] = globalContext.AO
    }
    所以结果为10
    
    

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

    var x = 10;
    bar()
    function bar(){
      var x = 30;
      function foo(){
        console.log(x)
      }
      foo();
    }
    
    1
    globalContext {
      AO: {
        x: 10;
        bar: function;}
    }
    bar.[[scope]] = globalContext.AO
    
    2
    barContext {
      AO: {
        x: 30
        foo: function
      }
    scope: bar.[[scope]] = globalContext.AO
    }
    foo.[[scope]] = barContext.AO
    
    3
    fooContext {
      AO: {}
      scope: foo.[[scope]] = barContext.AO
    }
    
    所以结果为30
    

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

    var x = 10;
    bar()
    function bar(){
      var x = 30;
      (function (){
        console.log(x)
      })()
    }
    
    1
    globalContext {
      AO: {
        x: 10;
        bar: function
        }
    }
    bar.[[scope]] = globalContext.AO
    
    2
    barContext {
      AO: {
        x:30
        console.log(x): 30  //输出
      }
    scope: bar.[[scope]] = globalContext.AO
    }
    
    所以结果为30
    

    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)
    
    1
    globalContext {
      AO: {
        a: 1
        fn: function
        fn3(): function
      }
    }
    fn.[[scope]] = globalContext.AO
    fn3.[[scope]] = globalContext.AO
    
    2
    fnContext {
      AO: {
        a: 5
        fn2: function
      }
    scope: fn.[[scope]] = globalContext.AO
    }
    fn2.[[scope]] = fnContext.AO
    
    fn3Context {
      AO: {
      }
    scope: fn3.[[scope]] = globalContext.AO
    }
    
    fn2Context {
      AO: {
      }
    scope: fn2.[[scope]] = fnContext.AO
    }
    
    所以结果
    fn()  //undefined 5 1 6 20
    console.log(a) //200
    
    对于undefined:声明前置,会声明var a,此时a为undefined
    
    对于fn2() //6:fn3()运行后,对a赋值,此时globalContext.AO{a:200},但是,函数是一个作用域链,对于fn2(),a++后,fnContext.AO{a: 6}
    
    对于20:fn2()运行后,对a赋值,所以此时的fnContext.AO{a: 20}
    
    

    相关文章

      网友评论

          本文标题:函数与作用域

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