引用类型-Function类型

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法;由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定

1.函数声明和函数表达式
  • 定义函数的方式有2种:函数声明和函数表达式
  • 写法区别:
function getName(name){          //函数声明,使用关键字function
     console.log(name);
}
var getName = function(name){    //函数表达式,将函数整体赋值给变量,这种情况下创建的函数叫做匿名函数
   console.log(name);
}
  • 声明前置区别:
getName("hunger");      //hunger,因为函数声明会前置(类似变量提升)
function getName(name){
    console.log(name);
}
getName("hunger");     //报错getName is not a function,因为函数表达式没有前置
var getName = function getName(name){
      console.log(name);
}
2.变量的声明前置与函数的声明前置
  • 变量声明前置
console.log(a);     //undefined,变量提升,将var a;提升至作用域最前面;当执行到var a = 1;时再进行赋值
var a = 1;
  • 函数声明前置(function declaration hoisting):执行代码之前会先读取函数声明
getName("hunger");            //hunger,函数声明前置,将整个函数放置作用域最前面
function getName(name){
      console.log(name);
}
3.参数
  • ECMAScript中的参数在内部是用一个数组来表示的
  • 实际上,函数内部可以通过arguments——这个类数组对象访问参数列表,该对象具有length属性,仅在函数内部有效
function getInfo(name,age,sex){
    console.log(name);
    console.log(age);
    console.log(sex);
    console.log(arguments);                      //["Amy", 17, "female"],实参具体内容
    console.log(arguments.length);               //3,实参的个数
    console.log(arguments[1]);                   //17,可通过下标操作实参
  }
  getInfo("Amy",17,"female");                    //Amy 17 femal 
  • 没有传递值的命名参数,默认为undefined;就像只声明变量但没有初始化一样
function sum(num1,num2,num3){
    console.log(num1);
    console.log(num2);
    console.log(num3);
}
sum(1,2);                            //1 2 undefined
4.函数的重载
  • 函数重载:相同名字的函数参数个数不同或者顺序不同、接受的参数类型不同都被认为是不同的函数
  • 在JS中没有函数重载的概念,函数只通过名字确定唯一性,即使参数不同也被认为是相同的函数,后面的覆盖前面的
function getInfo(name){
      console.log("name"+name);
 }
function getInfo(name,age){
      console.log("name:"+name+","+"age:"+age);
}
getInfo("Amy");                   //name:Amy,age:undefined,覆盖了第一个function
  • 实现重载:可以使用arguments判断参数类型或者个数等分情况操作
function getArguments(){
    if(arguments.length == 1){
        var name = arguments[0];
                getInfo1(name);
    }else{
        var name = arguments[0];
        var age = arguments[1];
                getInfo2(name,age);
    }
}
function getInfo1(name){
      console.log("name:"+name);
}
function getInfo2(name,age){
     console.log("name:"+name+","+"age:"+age);
}
getArguments("Amy");               //name:Amy
getArguments("Asher",4);           //name:Asher,age:4
5.立即执行函数表达式是什么?有什么作用
  • 立即执行函数是一种表达式(function(){})();可以理解为(函数定义表达式)函数调用表达式
(function f(f){
        return typeof f();
})(function(){return 1;});         // "number"
  • 立即执行函数模仿块级作用域:JS本身是没有块级作用域的概念的
(function(){
        //这里就是块级作用域
})()
6.写一个函数,返回参数的平方和
function sumOfSquares(){
      var sum = 0;
      for(var i=0;i<arguments.length;i++){
           sum += arguments[i] * arguments[i];
      }
console.log(sum);
}
sumOfSquares(2,3,4);   // 29
sumOfSquares(1,3);   // 10
7.以下代码分别输出什么,为什么
console.log(a);          //undefined   变量提升
var a = 1;
console.log(b);          //Uncaught ReferenceError: b is not defined    因为b没有声明
sayName('world');                       //hello  world   函数声明前置
sayAge(10);                               //Uncaught TypeError: sayAge is not a function   函数表达式没有前置
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};
function fn(){}
var fn = 3;
console.log(fn);          //3   分别声明前置和变量提升,然后fn被赋值为3
//浏览器引擎将以上代码理解为:
function fn(){}         //首先,同一作用域内重复声明,函数声明会提升至变量声明之前
var fn;
fn = 3;
    function fn(fn2){
       console.log(fn2);            //fn2函数体
       var fn2 = 3;
       console.log(fn2);           //3
       console.log(fn);            //fn函数体
       function fn2(){
            console.log('fnnn2');
        }
     }
    fn(10);
//可理解为以下伪代码:
        function fn(fn2){
            var fn2 = 10;                 //首先,传参,赋值
            function fn2(){               //函数声明前置并且提升至变量声明之前
                console.log('fnnn2');
            }
            var fn2;                         //变量声明前置
            console.log(fn2);
            fn2 = 3;                        //赋值,fn2的值改变
            console.log(fn2);
            console.log(fn);
            
        }
        fn(10);
var fn = 1;
function fn(fn){
    console.log(fn);
}
console.log(fn(fn));              
//Uncaught TypeError: fn is not a function
//函数声明前置之后被变量赋值覆盖,因此最后 fn=1 而报错
    fn();
    var i = 10;
    var fn = 20;
    console.log(i);                 //10
    function fn(){
        console.log(i);          //undefined
        var i = 99;
        fn2();
        console.log(i);        //100
        function fn2(){
            i = 100;
        }
    }
//可理解为以下伪代码:
    function fn(){
           function fn2(){
            i = 100;
           }
           var i;
           console.log(i);         //此时i还并没有被赋值,因此返回undefined
           i = 99;
           fn2();                //执行fn2之后,i被赋值为100,覆盖 i = 99;
           console.log(i);         //因此这时返回100
        
    }
    var i;
    var fn;
    fn();        
    i = 10;
    fn = 20;
    console.log(i);     //遵循作用域链,全局作用域下的i返回10
        var say = 0;
        (function say(n){
            console.log(n);         //依次返回10,9,8,7,6,5,4,3,2  立即执行函数,即声明之后立即执行
            if(n<3) return;
            say(n-1);
        }( 10 ));
        console.log(say);         //0  返回全局变量say,此时变量say已覆盖函数say
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • Function类型 函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和...
    胖胖冰阅读 944评论 0 8
  • 函数声明和函数表达式有什么区别 (*)解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;函数表达式则必须...
    coolheadedY阅读 388评论 0 1
  • 函数是对象,每个函数都是Function类型的实例,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。 ...
    shanruopeng阅读 196评论 0 2
  • 1、函数声明与函数表达式的区别 函数声明可以将函数的使用提升到函数所在语句之前,而函数表达式则不行,必须要在函...
    hahaheyliu阅读 98评论 0 1
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,739评论 2 17