javascript中的函数知多少?

javascript函数

函数是 JavaScript 中的基本组件之一。一个函数是 JavaScript 过程是一组执行任务或计算值的语句。要使用一个函数,你必须将其定义在你希望调用它的作用域内。

当函数是一个对象的属性时,被叫做方法。

在javascript中,函数是头等对象,因为它们可以像任何其他对象一样具有属性和方法。它们与其他对象的区别在于函数可以被调用。它们是Function对象。

如何定义函数

使用函数声明

一个函数定义(或称函数声明,或称函数语句)是由function关键字和语句组成。有函数名称,函数参数列表,多个参数用逗号分隔,定义函数的语句,用大括号{}包裹。

示例:定义一个简单的addSum函数:

function addSum(x, y) {
  return x + y;
}

函数的名称叫addSum,它有两个参数,大括号中的语句将该函数的参数相加后返回。函数 的return语句确定了函数的返回值。如果函数中没有return语句,默认返回undefined

参数是原始参数(如数字,字符串,布尔值)作为值传递给函数,如果被调用函数改变了这个参数的值,不会影响到全局或调用函数。

参数如果是非原始值(如对象或数组),函数改变了这个非原始值的内容,这个改变会影响到函数外部的非原始值的内容。

函数生成器声明(function*语句)

函数声明有一种特殊的语法

function* name(param) { statements }

使用函数表达式

使用函数表达式来创建函数,这个函数可以是匿名的,也可以提供函数名。

方式一(匿名函数表达式)示例:

const addSum = function (x, y) {
  return x + y;
}
let sum = addSum(1, 3)

方式二(带函数名的函数表达式)示例:

const addSum = function fn (num) {
  return num <= 1 ? 1 : fn(num - 1);
}
let sum = addSum(3)

当不以function开头的函数语句就是函数表达式定义。

当函数只使用一次,通常使用IIFEIIEF是在函数声明后立即调用的函数表达式。

(function() {
    statements
})()

函数生成器表达式(function*表达式)

function* [name](param) { statements }

构造函数表达式和函数声明类似,有着相同的语法,函数名称可以被省略。

箭头函数表达式(=>)

(params) => { statements }

Function构造函数

不推荐使用Function构造函数创建函数,因为它需要的函数体作为字符串可能会阻止一些JS引擎优化,也会引起其他问题。

new Function(...args)

如何调用函数

函数只有被调用后才会执行,函数不会自动执行。

函数调用时一定要处于声明它的函数域(指函数声明时所在的地方,或者函数在顶层被声明时指整个程序)中,但是函数的声明可以被提升(函数提升仅适用于函数声明的方式,不适用于函数表达式)。

正确示例:

// 方式一:addSum(1, 4),使用函数声明方式可以提升

function addSum (x, y) {
  return x + y;
}

// 方式二:addSum(1, 4) // 正常调用函数

函数可以调用自身,即递归函数。递归近似于循环,两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环或无限递归)。

// 计算阶乘
function factorial(n){
  if ((n == 0) || (n == 1))
    return 1;
  else
    return (n * factorial(n - 1));
}

错误示例:

addSum(1) // Uncaught ReferenceError: Cannot access 'addSum' before initialization

const addSum = function fn (num) {
  return num <= 1 ? 1 : fn(num - 1);
}

函数的参数

调用函数时,传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名被叫作形参。

ES6中,函数有两个新的类型的参数:默认参数和剩余参数。

默认参数

在javascript中,函数参数的默认值是undefined,然而,在某些情况下设置不同的默认值是有用的。

function outside(x, y = 1) {
  return x * y;
}

剩余参数

剩余参数允许将不确定数量的参数表示为数组。

function getArgs(x, ...args) {
  return args;
}
getArgs(10, 11, 2, 4, 5) // [11, 2, 4, 5]

什么是函数作用域

在函数内定义的变量不能在函数之外的任何地方访问,因为变量仅在该函数的域内部有定义。相对应的,一个函数可以访问定义在其范围内的任何变量和函数。换言之,定义在全局域中的函数可以访问所有定义在全局域中的变量。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何其他变量。

函数中使用arguments对象

函数的实际参数会被保存在一个类似数组的arguments对象中,

function outside(x, y) {
  console.log(arguments) //Arguments(2) [10, 11, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
outside(10, 11)

使用 arguments 对象,你可以处理比声明的更多的参数来调用函数。这在你事先不知道会需要将多少参数传递给函数时十分有用。你可以用arguments.length来获得实际传递给函数的参数的数量,然后用arguments对象来取得每个参数。

注意:arguments变量只是类数组对象,并不是一个数组,叫类数组对象是说它有一个索引编号和length属性,但它并不拥有数组全部的操作方法。

箭头函数

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisarguments,supernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且箭头函数不能用作构造函数。

var Foo = () => {};

更多关于箭头函数的内容参考下一部分内容。

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

推荐阅读更多精彩内容

  • 通常来说,一个函数就是一个可以被外部代码调用(或函数本身递归调用)的“子程序”。和程序本身一样,一个函数的函数体是...
    betterwlf阅读 482评论 0 0
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,556评论 0 5
  • 定义函数 - 函数声明和函数表达式 函数声明 注意 当函数的参数是一个值,若被调用函数改变了这个参数的值,这样的改...
    你期待的花开阅读 432评论 1 8
  • 查阅书籍:JavaScript权威指南 函数声明与函数表达式 用函数声明定义的函数,函数可以在函数声明之前调用,而...
    雪萌萌萌阅读 353评论 1 9
  • 正如上篇文章介绍的那样,作用域包含了一些列的”气泡“,每一个都可以作为容器,其中包含了标识符(变量、函数)的定义,...
    指尖的宇宙阅读 310评论 0 1