JavaScript 函数

一、什么是函数

函数:一般是由事件驱动的,为了实现特定功能,可以重复调用的一段可以执行的代码块。

二、函数的分类

从定义角度分:内置函数、用户自定义函数

内置函数:字符串,数学函数,数组函数,js 系统给我们提供的函数

自定义函数:自己定义的函数:函数的声明

从参数的角度分:有参函数、无参函数

从返回值的角度分:有返回值函数、无返回值函数

(1)无参无返回值函数的定义与调用:

function 函数名称(){

    函数体;

}

函数名()

(2) 有参无返回值函数:

function 函数名称(形参1,形参2,形参3...){

    函数体;

}

函数名称(实参1,实参2,实参3...)

1、形参:定义函数时所用的参数称为形参

形参的本质是用来接收函数调用时传递过来的数据的存储空间;

形参只有在函数调用时才开辟空间,当函数执行完毕后,该空间被释放。

形参只能在函数内部使用,因为它属于局部变量

2、实参:调用函数时使用的参数称为实参

实参的本质是函数要处理的具体的数据

一个函数可以有多个实参,用逗号分隔,形成“实参列表”

实参可以是字面量、变量、表达式

3、实参和形参的关系

1)函数被调用时,实参会被传递给形参,但是形参不能传递给实参,即传递是单项的;

2)默认情况下实参和形参在数据传递时是平行传递的,即第一个实参传递给第一个形参,第二个实参传递给第二个形参,以此类推;

3)js 中形参的个数和形参的个数可以是不一致的,如果实参 小于 形参,那么没有介绍的数据的形参的值为 undefined;

(3) 有参返回值函数的定义格式

function 函数名称(形参1,形参2...){

    函数体;

    return 返回值

}

var 变量 = 函数名称(实参1,实参2...)

三、值传递和地址传递

值传递:指将具体数据(基本类型的数据)的副本传递给对方,对方在操作这个数据时不影响原始数据

var arr = [10,20,30,40,50];

function fn(val){

    val = 100;

}

fn(arr[0]); //调用函数 fn 时传递的时 arr[0]中数据的副本-----值传递

console.log(fn(arr[0]));//原数组不受影响

地址传递:指将引用类型的数据在对内存中的地址传递给对方,对方在操作时,其实操作的就是原始数据,即原有数据被影响

var arr = [10,20,30,40,50];

function fn(val){// val 指向了数组

    val[0] = 100;

}

fn(arr); //数组名称中保存的是数组在堆内存中的地址--------地址传递

console.log(arr);//原数组中的值变了

四、return 返回值

1、返回值:指函数被调用后,向调用者返回的一个数据,函数内部利用 return 关键字将返回值返回

2、return 关键字的使用格式: return 返回值;

3、return 使用时的注意事项:

1)返回值可以是变量,字面量,表达式

2)函数内部可以有多个 return, 但是只能执行一个,return 关键字除了返回数据,还具有结束函数执行的功能

3)如果函数中没有设置 return ,那么在调用函数时,其实后台会向调用者返回一个值 ---- undefined

4)在定义函数时,return 和它后面的返回值不要换行,因为换行后,后台会认为 return 后面没有返回值。

5)如果要将 return 用左结束函数的功能,那么可以采用 return 的格式;

五、定义函数的方式

1、函数声明的方式

function 函数名称(){

    函数体;

}

函数名称();

2、函数表达式

var 变量名称 = function(){

    函数体;

};

var fn = function(){

    for (var i = 1; i <= 10; i ++){

        if ( i % 2 == 0 ){

            console.log(i)

        }

    }

};

fn();

1)函数表达式方式创建的函数是没有名称的函数

2)变量中存储的是对函数的引用

3)函数声明方式和函数表达式方式的区别,函数声明方式定义的函数可以在定义之前调用该函数,但是函数表达式方式定义的函数,不可以在定义之前调用。因为函数声明方式定义的函数有函数声明提升操作,而函数表达式方式定义的操作没有函数声明提升操作,只有变量声明提升操作

3、利用 function 构造方法创建函数

var 变量名称 = new function('参数1','参数2'...);

调用方式:

变量名称(实参1 , 实参2, 实参3...);

构造方法 function 中的参数可以有多个,那么前面的参数表示函数的形参,最后一个参数表示函数体。

注意: 这种方式定义的函数也不可以在定义之前调用,因为它也只有变量声明提升操作

var add = new  function('num1','num2','num3','var sum = num1+ num2 + num3; console.log(sum);');

add(1,2,3);

六、 变量的分类:全局变量、局部变量

全局变量:定义在函数外部的变量被称为全局变量;

局部变量:定义在函数内部的变量被称为局部变量。

区别: 1、全局变量可以在整个文档中使用

2、局部变量只能在定义它的函数内部使用

3、函数内部的形参也是局部变量,也只能在函数内部使用

4、如果全局变量和局部变量同名,那么全局变量会被屏蔽

5、如果局部变量和全局变量同名,那么要使用全局变量,可以在变量名称前面加 window. 或者 this.  ,因为全局变量是给 window 对象绑定的属性

七、 arguments 对象

1、arguments:该对象是函数内部的一个对象,即该对象只能在函数内部使用,不可以在外面使用。它的作用是用来管理函数被调用时传递过来的实参(数据),它不是一个数组,它是一个伪数组,在管理实参时也是用下标的方式对实参进行了编号,即可以使用 arguments[下标]的形式操作实参。

2、形参 和 arguments 的关系: 形参和 arguments 都可以管理实参,而且他们管理的是同一份数据。在操作实参时,可以使用形参,也可以用 arguments , 为了方便通常使用形参。

在定义函数时,到底需不需要定义形参?

--- 如果实参的个数是确定的,那么我们就定义形参,如果实参的个数是不确定的时候就不定义形参,用 arguments 操作

3、arguments 对象包含两个属性: length、callee

1)length 属性: 获取实参个数;

2)callee 属性: 该属性的作用是用来获取 arguments 对象所在的函数,即callee 属性指向了 arguments 对象所在的函数,常与递归函数结合使用,或与匿名自执行函数结合使用。

--- 如果要判断一个元素是否为数组, 那么可以使用 Array.siArray 方法

1、 格式: Array.isArray(数据);

2、返回值: true(是数组) 、 false(不是数组)

var arr = [1,2,3];

var res = Array.isArray(res);

console.log(res);

八、JavaScript 中没有重载函数

重载函数:所谓重载函数就是指,两个函数的名称相同,但是他们形参的个数不同,或者形参的类型不同,那么我们把这两个函数互称为重载函数

function fn(a,b){

}

function fn(a,b,c){

}

//这两个互称为重载函数

// 注意: JavaScript 中没有重载函数,在JavaScript 中,如果函数名称相同,那么后面的函数会覆盖前面的函数

利用 arguments 对象模拟重载函数

function fn(){

    if(arguments.length == 1){

        console.log('只有一个形参' +i);

    } else if(arguments.length == 2){

        console.log('有两个形参' + i)

    }

}

fn();

九、递归函数:

递归函数:所谓递归函数就是指在一个函数内部调用了自己的函数被称为递归函数。

function fn(){

    fn();

}

fn();

注意:在使用递归函数时,一定要确定递归函数的“出口”,即在某个时刻能够让函数不再调用自己,如果递归函数没有出口,那么会出问题。

function fn(n){

    if(n == 1){

        return 1;

    }

    return arguments.callee(n - 1) +n;//推荐递归函数内部使用 arguments.callee 属性来引用当前函数

}

十 、匿名函数

概念: 没有函数名称的函数;匿名函数可以和事件相结合,常用格式如下:

html 元素 . on事件名称 = function(){

};

十一 、 回调函数

概念: 如果一个函数被当作另外一个函数的参数,那么这个被作为参数的函数就是回调函数,回调函数常用匿名函数;

var arr = [1,2,3,4,5];

var res = sort(function(a,b){

    return a -b;

})

console.log(res);

十二、 匿名自执行函数

概念: 没有名称,且不需要手动调用的函数,

格式:

1、无参五返回值的匿名自执行函数

(function(){

    函数体;

})();

2、有参无返回值的匿名自执行函数

(function(形参1、形参2、形参3...){

    函数体

})(实参1、实参2、实参3...)

3、有参有返回值的自执行函数

var 变量名称 = (function(形参1、形参2...){

    函数体;

    return 返回值;

})(实参1、实参2...)

注意:匿名自执行函数,通常用来创建块级作用域。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容