美文网首页
函数与作用域

函数与作用域

作者: BAWScipes | 来源:发表于2017-09-23 14:54 被阅读0次
    1.函数声明和函数表达式有什么区别
      //函数声明
      function sayHi(){  console.log("Hello"); }
      //函数表达式
      var sayHi = function (){ console.log("Hello"); }
      //函数调用
      sayHi();
    

    函数声明:使用function关键字声明函数,声明不必放到调用的前面
    函数声明在执行代码之前就会读取函数声明
    函数表达式:创建一个匿名的函数声明并赋值给变量,声明必须放到调用的前面
    函数表达式定义的函数在使用之前先赋值
    参考 参考

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

    变量声明前置就是在一个作用域中,所有的变量都被放在作用域的顶部声明,举例:

      console.log(a);
      var a=3;
    

    返回结果是undefined,说明变量在前面就已经声明了,这就是变量声明前置
    函数声明前置把函数提升到作用域的顶部声明(函数表达式不可以),举例:

      sayHello();
      sayHi();
      function sayHello(){
        console.log("hello");
      }
      var sayHi=function(){ 
        console.log("hi");
      }
    

    sayHello()返回结果是 "hello",说明函数声明进行了声明前置,函数声明被提升到了前面
    sayHi()报错,说明函数表达式未进行函数声明前置,按从上往下的顺序执行到sayHi()时未解析到函数。

    3.arguments是什么

    arguments是一个类数组对象,类似数组的方式,可以通过下标的方式去获取值,但它本身不是数组,没有数组的一些特性,所以叫类数组对象。
    在函数内部,可以使用arguments对象获取到该函数的所有传入参数

      function printPersonInfo(name,age,sex){
          console.log(arguments);
      }
      printPersonInfo("小谷",12 , "male")
    

    参考

    4.函数的“重载”怎样实现

    重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
    JS并不像其他强类型语言一样可以声明重载函数,若在原先声明的函数后再声明一个不同参数数量的函数(JS是弱语言,声明的函数不需要指明参数类型),解析器会用后面声明的函数覆盖前面声明的函数。
    函数的重载实现方法:
    (1)在函数体针对不同的参数调用执行相应的逻辑

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

    (2)使用arguments属性

      function printPeopleInfo(name, age, sex){
        console.log(arguments);
      }
      printPeopleInfo('Byron', 26);
      printPeopleInfo('Byron', 26, 'male');
    
    5.立即执行函数表达式是什么?有什么作用

    参考

     (function(){ var a=1; })();
     (function(){ var a=1; }());
    

    注意:当圆括号出现在匿名函数的末尾想要调用函数时,它会默认将函数当成是函数声明。
    当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明。
    作用:隔离作用域

    6.求n!,用递归来实现
      function factor(n){
        if(n===-1){
          return 0;
        }
        if(n===0||n===1){
          return 1;
        }
        if(n<-1){
          return false;
        }
        return n*factor(n-1);
      }
      factor(10);
    
    7.以下代码输出什么?
      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: 男  ["饥人谷", 2, "男"]  name valley
    name: 小谷  age: 3  sex: undefined  ["小谷", 3]  name valley
    name: 男  age: undefined  sex: undefined  [ "男"]   name valley
    
    8.写一个函数,返回参数的平方和?
       function sumOfSquares(){
         var sum=0;
         for(var i=0;i<arguments.length; i++){
            sum=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);  //报错
    

    输出结果: undefined 报错
    变量声明前置,顺序相当于

    var a;
    console.log(a);   //a声明未赋值,输出undefined
    a=1;
    console.log(b);  //没有变量b,报错
    
    10.如下代码的输出?为什么
       sayName('world');
       sayAge(10);
       function sayName(name){
        console.log('hello ', name);   //hello world
       }
       var sayAge = function(age){
            console.log(age);    //报错
       };
    

    输出结果:hello world 报错
    函数声明,声明不必放在调用前面;而函数表达式,声明必须放在调用的前面
    sayAge(10);先调用,没有声明,所以报错

    11.以下代码输出什么? 写出作用域链查找过程伪代码
      var x = 10
      bar() 
      function foo() {
        console.log(x)
      }
      function bar(){
        var x = 30
        foo()
      }
    

    输出结果:10,作用域链查找过程伪代码如下:

    1.
      globalContext = {
        AO: {
          x:10
          bar: function
          foo: function
        }
        Scope: null
      }
      bar.[[scope]] = globalContext.AO
      foo.[[scope]] = globalContext.AO
    2.
      barContext = {
      AO: {
        x: 30
      }
      Scope: bar.[[scope]] = globalContext.AO
      }
    3.
      fooContext = {
      AO: { }
      Scope: foo.[[scope]] = globalContext.AO
      }
    
    12.以下代码输出什么? 写出作用域链查找过程伪代码
      var x = 10;
      bar() 
      function bar(){
        var x = 30;
        function foo(){
          console.log(x) 
        }
        foo();
      }
    

    输出结果: 30,作用域链查找过程伪代码:

    1. globalContext = {
         AO: {
              x: 10;
              bar: function
          }
          Scope: null
        }
        bar.[[scope]] = globalContext.AO
    2. barContext = {
        AO: {
            x: 30
            foo: function
          } 
          Scope: bar.[[scope]] = globalContext.AO
        }
    3. fooContext = {
        AO: { }
        Scope: foo.[[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.[[scope]] = globalContext.AO
    2. barContext = {
          AO: {
              x: 30
          }
          Scope: barContext .AO
        }
    3. 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 1 6 20 200,作用域链查找过程伪代码:

    1. globalContext = {
          AO: {
            a: 1;  //200
            fn: function;
            fu3: function;
          }
        Scope: null
        }
        fn.[[scope]] = globalContext.AO
        fn3.[[scope]] = globalContext.AO
     2. fnContext = {
          AO: {
             a: undefined;  //5  6 20 
             fn2: function
          }
          Scope: globalContext.AO
        }
       fn2.[[scope]]=fnContext.AO
    3. fn3Context = {
          Ao: { }
          Scope: globalContext.AO
       }
    4. fn2Context = {
          Ao: { }
          Scope: fnContext.AO
       }
    

    相关文章

      网友评论

          本文标题:函数与作用域

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