【21】JavaScript (函数)

1 函数

1.1 什么是函数

  • 函数就是具有特定功能的代码块,可以被多次调用
  • 函数是 JavaScript 中的一种数据类型,属于对象类型; 使用 typeof 判断可以返回 function

1.2 函数的组成

  • 函数名: 函数名本质上是个变量,函数名的命名规则与变量名的命名规则一致。
  • 参数: 参数本质上是个变量,只能在函数内使用,在调用函数的时候才能被赋值。
  • 函数体: 用大括号包裹的代码块。
  • 返回值:返回值是函数的计算结果, 作为函数调用表达式的值

1.3 声明函数

① function 关键字方式

function 函数名() {
    函数体语句 ...;
}

function 函数名(参数列表...) {
    函数体语句 ...;
}

② 表达式方式

var 函数名 = function() {
    函数体语句 ...;
}

var 函数名 = function(参数列表...) {
    函数体语句 ...;
}

1.4 函数调用和返回值

① 函数调用

  • 函数名()才是函数调用,函数体语句才能执行,才能得到函数的返回值。
  • 函数名后面没有括号,就是在使用一个变量,函数体语句不会执行,也得不到函数的返回值。

② 返回值

1. 返回值是函数的计算结果,是函数调用表达式的值(函数名加括号就是函数调用表达式)
   var res = fn();    // 把函数的返回值赋值给变量 res
   fn() + 100;        // 函数的返回值与 100 相加
   console.log(fn()); // 输出函数的返回值

2. 通过 return 关键字定义函数的返回值
   return 需写在函数体内,return 右边需写一个表达式(变量、直接量、带运算符的表达式), 表达式的值就是函数的返回值。
   如果 return 右边是空的,函数没有返回值, 没有返回值函数调用表达式的值会自动得到 undefined

3. return 还可以结束函数的执行; 一旦执行到 return,后面的语句就不会执行了。

1.5 函数的参数

①形参和实参

形参:函数声明时设置的参数,相当于没有赋值的变量,必须以变量名的形式给出。

实参:调用函数时所给的参数,用于给形参赋值, 可以是变量、直接量、表达式等形式。

② 形参和实参的数量问题

标准情况下,形参和实参的数量应一致,按顺序赋值,如果:

形参数量 > 实参数量:后面的形参没有被赋值,自动得到 undefined。

形参数量 < 实参数量:多余的实参则没有用。

③ 形参的默认值(可选参数)

  1. 具有默认值的参数即可选参数
  2. 可选参数应放在必选参数的后面,因为实参按顺序给形参赋值,不给实参则可以返回默认值。

ES5 规范中设置默认值的方式:

function fn(name, age) {
    // 如果 age 没有对应的实参, 设置一个默认值
    if (age === undefined) {
        age = 默认值;
    }
}

ES6 规范中的设置默认值的方式:

funciton fn(name, age=默认值) {
    
}

④ arguments关键字

  1. arguments 是系统定义好的变量,可以直接使用,但只能在函数内使用, 在函数外使用则会报错。
  2. arguments 是个伪数组对象,里面的成员是函数调用时传进来的实参; arguments 具有length 属性,可以通过索引获取到其中的每个成员。
  3. arguments 是除了形参之外另外一种获取实参的方式。 形参只能获取固定数量的实参,arguments 可以获取所有的实参。
  4. 使用 arguments 可以定义可变参数数量的函数。
// 计算所有参数的和,返回结果
function sumFn() {
    // 定义变量 记录和
    var sum = 0;
    // 遍历 arguments
    for (var i = 0; i < arguments.length; i ++) {
        sum += arguments[i];
    }
    // 返回结果
    return sum;
}

1.6 作用域

① 变量的作用域

作用域即变量的可作用范围,根据作用域不同,变量可分为全局变量局部变量

全局变量: 在函数以外定义,作用域是全局。如:函数外声明的函数,函数内没有用var声明的变量。

局部变量: 在函数内定义,作用域是所在的函数。如:函数的形参,函数内声明的函数。

  1. 函数名本质上是变量,所以函数本身也有作用域,由函数是在哪里声明的决定。
  2. 如果在函数里不使用var声明变量,该变量是全局的(严格模式下不允许不使用var声明的变量的)

② 作用域链

函数里还可以继续声明函数,函数的嵌套关系形成了作用域链,函数内可以使用本层作用域和上层作用域中的变量。

作用域链描述变量查找的过程:

当使用某个变量的时候,先从本作用域中查找,如果找不到就去上层作用域查找,哪里找到哪里停止,找不到则继续向上查找,直到全局作用域,如果仍然没有查找到该变量,则报错。

注:变量的作用域只与函数声明的位置有关系,与函数在哪里调用无关。

1.7 变量提升

① 变量提升

  1. 代码正式执行之前,会进行预解析,预解析时会把变量提升到本作用域的最前面(只创建了变量,却没有赋值)
  2. 全局变量在整个代码正式执行之前就发生了提升
  3. 局部变量在函数体语句执行之前进行提升

② 函数提升

  1. 函数名本质上就是变量,所以函数也会提升到本作用域的最前面。
  2. 使用 function 关键字形式声明的函数,提升比较彻底,代码执行之前不但创建了函数名并且有值。
  3. 使用表达式方式声明的函数,提升规则与普通变量没有差别。
  4. 函数提升与变量提升的区别:
    ① 函数提升更彻底
    ② 正式执行代码的时候,执行到变量声明并赋值的语句会进行赋值操作, 执行到函数声明语句会跳过

1.8 匿名函数

即没有名字的函数,用函数这种数据类型的直接量表示,适合作为自调用函数回调函数

1.9 自调用函数(立即执行的函数)

函数声明完立即被调用,主要作用是用来产生作用域,避免全局变量污染。一般以匿名函数作为自调用函数,有名字的函数也可以作为自调用函数,但没有必要。

// 匿名的自调用函数(立即执行的函数)
(function() {
    函数体语句;
})();

// 有名字的自调用函数
(function fn() {
    函数体语句;
})();

// 匿名的自调用函数 设置参数
(function(形参1, 形参2) {
    函数体语句;
})(实参1, 实参2);

1.10 回调函数

具有以下三个条件的函数称为回调函数:

  • ① 函数是我定义的
  • ② 我没有直接调用该函数
  • ③ 函数却执行了

注意: 回调函数大部分情况会作为其他函数(或方法)的参数。

1.11 递归函数

函数内部再次调用自己。

① 递归成功的条件:

  • 有明确的结束递归的条件
  • 有一个趋向于结束递归调用的趋势

② 递归函数的缺点

  • 可能发生内存泄漏
  • 效率不高

③ 递归函数应用场景

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

推荐阅读更多精彩内容