美文网首页
函数-Assignment

函数-Assignment

作者: 犯迷糊的小羊 | 来源:发表于2016-06-17 00:02 被阅读126次

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

    • 函数声明后面的分号可加可不加,不影响接下来的语句,但是函数表达式后面没有分号结束,js引擎则会认为后面的内容仍是函数表达式的一部分
    //没加分号报错
    var a = function(){}console.log("")
    //没加分号不报错
    function b(){}console.log("")
    
    • 变量提升时,函数声明将作为整个代码块一起提升至作用域的最上面;函数表达式则是提升变量
    //提升变量var a
    var a = function(){};
    //提升函数function fn(){}
    function fn(){};
    

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

    JavaScript的解析代码时存在变量提升机制,具体流程是JS解析器在预执行(解析)阶段先会将所有的变量声明提升至该作用域的最顶部,然后在进行解析其余的代码
    这一机制同样适用于函数的声明,只不过函数声明的提升是将整个代码块一并提升

    3.arguments 是什么 (*)

    我们知道函数可以添加参数,而arguments对象包含了函数运行时的所有参数,但这个对象只能在函数体内部使用。

    function fn(a,b,c,d){
      console.log(arguments[0]);
      console.log(arguments[1]);
      console.log(arguments[2]);
      console.log(arguments[3]);  
    }
    fn(1,2,3,4);//1 2 3 4
    //使用arguments.length属性得知参数的个数
    function fn2(){
      console.log(arguments.length);
    }
    fn2(1,2,3,4)//4
    

    4.函数的重载怎样实现

    • 什么是重载函数
      允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数必须不同,这就是重载函数。

    • 重载函数的作用
      重载函数常用来实现功能类似而所处理的数据类型不同的问题。

    • JS的函数重载的实现
      在面向对象语言里重载是很重要的一个特性,而JavaScript这个自称面向对象的语言是没有直接提供重载。那么JavaScript是怎么实现(准确地讲应该叫“模拟”)的呢?
      利用arguments实现重载
      arguments是JavaScript里的一个内置对象,包含了调用者传递的实际参数,而调用时只它和数组一样有个length属性;
      我们暂且把它当“数组”来理解吧,我们根据该数组的长度以及其元素的类型来选择不同的实现,从而模拟了重载。
      给个例子:

    function getDate(){
    if(arguments.length==0){
    var date=new Date().toLocaleDateString();
    return "您没有输入参数,现在时间:"+date ;
    }
    if(arguments.length==1){
    if(arguments[0].constructor ==Date){
    return "您输入的参数是Date类型,现在时间是:"+arguments[0].toDateString();
    }
    if(arguments[0].constructor ==String){
    return "您输入的参数是String类型,现在时间是:"+arguments[0];
    }
    }
    }```
    于是我们可以这样调用:

    getDate()
    getDate(newDate())
    getDate("星期一")```
    **这样就实现了JavaScript的重载!**
    
    #### 4.立即执行函数表达式是什么?有什么作用
    
      - **什么是立即执行函数**
    一种声明之后就立即进行该函数执行操作的函数
      - **立即执行函数的写法**
    function()前面加任意符号,告诉js引擎这是要执行函数而不是声明函数,注意最后必须加分号
    
    

    写法1:
    (function fn(n){
    console.log(n)
    }());
    写法2:
    !function (){
    }();

      - **为什么要用立即执行函数**
        - 消除全局变量的污染;
        - 防止其他js文件出现与本文件的函数名重名情况,那么函数内部定义的          同一个变量a有可能被污染;
        - IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量
    
    #### 5.什么是函数的作用域链
    
    作用域是指变量存在的范围,可分为全局作用域和函数作用域,由此可划分变量为全局变量和局部变量
    
      - 全局作用域:变量作用范围是全局,直到js运行失效
      - 函数作用域:变量作用分为是函数内部,函数执行完后就失效
      - 作用域链:JavaScript语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量
    

    var a = 1;
    function fn(){
    var b = 2;
    c=3;
    console.log(a+b)
    }
    b//b is not defined
    //a是全局变量,只要js运行都会生效;
    //b是局部变量,只在函数体内部生效;
    //注意如果函数内部的变量不加var声明,那么会当做全局变量

    #### 6.以下代码输出什么?
    
    ![](https://img.haomeiwen.com/i1993435/e9b059bb0899a1b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    

    //getInfo('hunger', 28, '男');
    name: hunger
    age: 28
    sex: 男
    ["hunger",28,"男"]
    name: valley

    //getInfo('hunger', 28);
    name: hunger
    age: 28
    sex: undefined
    ["hunger",28]
    name: valley

    
    

    //getInfo('男');
    name: 男
    age: undefined
    sex: undefined
    ["男"]
    name: valley

    
    #### 7.写一个函数,返回参数的平方和
    
    ![](https://img.haomeiwen.com/i1993435/06ecb010fd130579.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    

    //这段函数实现的需求是:
    若输入的参数不是数值,则返回"输入值" is Not a number,接着会去计算那些数值项
    function sumOfSquares(x,y,z){
    var argu,sum=0;
    for(i=0;i<fn.length;i++){
    if (typeof arguments[i] !== "number") {
    console.log(arguments[i]+" " + "is Not a number!")
    } else {
    argu = Math.pow(arguments[i],2)
    sum += argu;
    }
    }
    console.log(sum);
    }
    sumOfSquares(1,3,9)//91
    sumOfSquares(1,3)//undefined is not a number 5

    
    ####8.  如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/4b48c65a66917034.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    undefined
    ReferenceError: b is not defined
    分析:
    上面的代码可以写成,
    var a;
    console.log(a);
    a=1;
    console.log(b);
    由于变量提升的缘故,变量a提升至作用域的最前面,所以第1个输出为undefind;
    第2个输出的变量b由于没有进行变量声明,所以出现ReferenceError:b is not defined;

    ####9.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/0933d45acde678da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    hello world
    "error"
    "TypeError: sayAge is not a function
    分析:
    这里使用函数声明和函数表达式分别定义两个函数sayName()和sayAge();
    在js引擎实际解析代码时,使用函数声明方法生命的sayName()会整个代码块提升至作用域顶部,而使用函数表达式定义的sayAge()则只会讲var sayAge提升至顶部;
    由此一来,造成上面两个函数在调用时,sayName()能够调用成功,而sayAge()则因为js引擎无法识别其为函数类型而报错

    ####10.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/7ded7b9459ed38f4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    上述代码等价于:
    function fn(){}
    var fn;
    fn=3;
    console.log(fn);
    //3
    同一个作用域内,变量和方法的命名相同,变量的赋值会覆盖方法的赋值,不论它们的顺序是怎样。

    
    ####11.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/3a77c15d47be2091.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    function fn2(){
    console.log('fnnn2');
    }
    3
    function fn(fn2){
    console.log(fn2);
    var fn2 = 3;
    console.log(fn2);
    console.log(fn);
    function fn2(){
    console.log('fnnn2');
    }
    }


    1.通过fn(10)调用函数fn,此时变量fn2=10;
    2.console.log(fn2)输出fn2的整个函数定义内容;
    3.fn2=3,然后执行console.log(fn2)操作而输出3;
    4.console.log(fn)输出fn的整个函数定义内容;

    ####12.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/456e769e4bcc996d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    输出结果:
    TypeError: fn is not a function
    上述代码等价于:
    var fn;
    function fn(fn){
    console.log(fn);
    }
    fn=1;
    console.log(fn(fn));
    此时,当变量名与函数名重名时,后出现的变量值会覆盖函数内容,只会把fn当做变量看待而不是函数,所以js引擎报错

    ####13.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/6c5f88f714477000.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    输出结果:
    undefined
    undefined
    10
    100
    上述代码等价于:
    var i;
    var j;
    console.log(j);
    console.log(i);
    for(var i=0; i<10; i++){
    var j = 100;
    }
    console.log(i);
    console.log(j);
    1.变量提升机制使得var i,j提升至作用域顶部;
    2.console.log(j)和console.log(i)输出结果均为undefined;
    3.for语句循环10次后退出循环,此时i=10,j=100;

    ####14.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/b536a067b0a2fd80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    输出结果:
    undefined
    100
    10
    上述代码等价于:
    var i;
    var fn;
    function fn(){
    console.log(i);
    var i = 99;
    fn2();
    console.log(i);
    function fn2(){
    i = 100;
    }
    }
    fn();
    i=10;
    fn=20;
    console.log(i);
    1.变量提升后,调用函数fn;
    2.此时i为赋值,所以console.log(i)为undefined;
    3.调用函数fn2,在fn作用域下返回全局变量i=100,所以执行第2个console.log(i)时显示100;
    4.最后i=10,执行第3个console.log(i)时显示10;

    ####15.如下代码的输出?为什么
    
    ![](https://img.haomeiwen.com/i1993435/d2be7971dcca080a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    输出结果:
    10
    9
    8
    7
    6
    5
    4
    3
    2
    0
    上述代码等价于:
    var say;
    //立即执行函数
    (function say(n){
    console.log(n);
    if(n<3) return;
    say(n-1);
    }( 10 ));
    say=0;
    console.log(say);
    1.执行立即执行函数,先输出原始参数10,然后执行判断语句,不符合条件语句后再次调用say()函数进行递归,直至参数n小于3后跳出函数体,期间输出值为10,9,8,7,6,5,4,3,2
    2.执行console.log(say),输出值为10

    相关文章

      网友评论

          本文标题:函数-Assignment

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