函数的详解

导读

  • 函数是什么
  • 创建函数的方法
  • 调用函数的方法
  • 变量作用域
  • 变量声明提升
  • 函数也是数据
  • 使用函数思想写程序的思路

函数是什么

函数是执行特定任务的代码块(代码块就是使用大括号包裹起来的语句的集合)。本质上函数是一种代码的分组形式。我们可以通过函数这种形式赋予某组代码一个名字,以便于之后调用。

示例:函数和函数调用

//函数声明
function sum(a,b){
   return a + b
}
//函数调用
sum(2,3) //5

特点1:函数只定义一次,可被调用任意次。

特点2:定义的函数永远不会执行,除非你调用它。

创建函数的方法

函数声明的语法

function funtionName(parameter1, parameter2, parameter3) {
  // code to be executed
}

函数声明是创建函数的一种方法。函数声明的过程通常由以下几部分构成。

1.function:关键词,用于声明函数。
2.函数名称:声明函数会创建一个变量,函数名称就是变量的名称,这是理解函数的关键。函数名称用于存放代码块。代码块相当于变量的值。
3.形参:形参就是变量,只是省略的声明变量的关键词var。它是小括号里用逗号分隔的参数。一个函数通常具有0个或多个形参。形参用于接收在函数调用时通过形参传入函数内的实参。
4.函数体 :使用大括号包裹的代码块。函数体相当于函数名的值。
5.return语句:如果你希望函数运行之后计算一个值,需要在函数内使用return语句显示设置返回值。return语句不是必须设置的,如果你没有在函数体内设置return语句,那么函数默认的返回值是undefiend。注意:一个函数只能有一个返回值,如果你需要返回多个值,可以考虑将多个值放入一个数组里,以数组元素的形式返回。

示例: 声明一个求平方的函数

function square(a){
  return a * a
}

示例: 声明一个判断一个字符串是否是包含数字的函数

function square(a){
  return a * a
}

示例: 声明一个判断一个值是否是奇数的函数

示例: 声明一个1位数字前置补0的函数

调用函数的方法

当创建了一个函数之后,如果需要使用它,就必须要去调用它,调用函数的方法很简单,只需要在函数名后加一对小括号即可。小括号内传入实际的参数,如果有多个参数,请使用逗号分隔。

语法

funtionName( 实参1,实参2,实参3,...,实参N )
  • 实参: 是调用函数时,通过形参传入到函数内的实际的参数。所有的实参都是为了计算函数返回值而出现的。

示例: 调用square()函数

square(10) // 100

思考:形参数量和实参数量是否必须一致?答案是否定的。了解相关内容,请查阅“arguments'对象。作为函数的初学者,最好让形参与实参数量保持一致。

变量作用域

变量作用域指定义变量的区域。 变量在哪个区域定义,就在哪个区域发生作用。变量作用域决定了变量的可访问性。在当前定义区域内,变量可以被访问到,在这个区域以外,变量不能被访问到。

有两种类型的作用域:

  • 全局作用域:局部作用域之外的区域就是全局作用域。
  • 局部作用域:局部作用域指函数作用域和块级作用域。这两种局部作用域使用不同的关键词
  • 定义
    • 函数作用域:指在函数体内,使用关键词var定义的变量,会创建变量的函数作用域,也就是说变量只能在当前函数体内才可以访问。注:变量定义在if或for创建的代码块内,是不会创建函数作用域的。
    • 块级作用域: 指在大括号包裹的区域内,使用关键词let或const定义的变量,会创建块级作用域,只能在大括号内才可以访问。

示例1: 函数作用域

function fn(){
  var a = 100
  console.log(a) // 100 (在函数体内可访问到变量的值)
}
console.log(a) // Uncaught ReferenceError: a is not defined(在函数体外访问不到变量的值)

示例2: let定义的变量存在块级作用域

{
  let a = 100
  console.log(a) // 100
}
console.log(a) // Uncaught ReferenceError: a is not defined

示例3: let定义的变量存在块级作用域(if语句)

if(true){
  let a = 100
  console.log(a) // 100
}
console.log(a) // Uncaught ReferenceError: a is not defined

示例4: let定义的变量存在块级作用域(for语句)

for (let i = 0; i < 3; i++) {
  console.log(i) // 0, 1, 2
}
console.log(i) // Uncaught ReferenceError: i is not defined

示例5: var定义的变量不存在块级作用域

{
  var a = 100
  console.log(a) // 100
}
console.log(a) // 100

示例6: var定义的变量不存在块级作用域

if(true){
  var a = 100
  console.log(a) // 100
}
console.log(a) // 100

示例7: var定义的变量不存在块级作用域

for (var i = 0; i < 3; i++) {
  console.log(i) // 0, 1, 2
}
console.log(i) // 3

示例

console.log(a) //
var a = 1

示例

console.log(a) //
let a = 1

示例

{
  var a = 1
}
console.log(a) //

示例

{
  let a = 1
}
console.log(a) // 

示例

var a = 1
function fn(){
  alert(a) //
  var a = 2
}
fn()
alert(a) //

示例

var a = 1
function fn(){
  alert(a) //
  a = 2
}
fn()
alert(a) //

示例

var a = 1
function fn(a){
  alert(a) //
  a = 2
}
fn(a)
alert(a) //

示例

var a = 1
function fn(a){
  alert(a) //
  a = 2
}
fn()
alert(a) //

示例

var str = ''
function fn(){
  var a = 'hello'
  str = a
}
fn()
alert(str) //

示例

function fn1(){
  var a = 'hello'
  fn2(a)
}
fn1()
function fn2(a){
  alert(a) //
}

示例

var a = 0
function fn1(){
  a++
}
function fn2(){
  a--
}
fn2()
fn1()
fn2()
alert(a) //

示例

alert(a)
if(true){
  var a = 1
}

示例

alert(fn)
function fn(){
 alert(123)
}

示例

alert(fn()) //
function fn(){
  alert(123)
}

示例

alert(fn)
if(true){
  var a = 1
  function fn(){
    alert(123)
   }
}

示例

alert(fn) //
var a = 1
function fn(a){
  alert(a)//
}

示例

alert(fn()) //
var a = 1
function fn(a){
  alert(a)//
}

示例

foo(); // 
var a = true;

if (a) {
  function foo() { console.log("a"); }
}
else {
  function foo() { console.log("b"); }
}

变量声明提升

变量声明提升是关于函数作用域的一个重要问题。先看一个的例子:

//请问console.log()第一次输出的是什么?
var n = 123
function fn(){
  console.log(n) //?
  var n = 456
  console.log(n)
}
fn()

您可能会想当然第认为第一次console.log()输出的是123,也就是全局变量n的值。但事实并非如此,第一个console.log()实际上输出的是undefined。因为在函数体内:变量n也有定义,故局部变量n会覆盖全局变量n。尽管在函数体内,第一次调用局部变量n的时候,n还没有定义,但n实际上已经存在于本地空间(函数体内)了,这种特殊现象叫做提升(hoisting) 。

提升(hoisting) :指当JS执行过程进入新函数时,新函数内的的所有变量声明(如var n)都会被提升到当前作用域的顶部。

示例:模拟变量声明提升

/**********************
var n  //变量声明被提升至顶部
*********************/
console.log(n) //undefined(在这里可以读取到n的原因就在于变量声明提升)
var n = 123

示例:模拟变量声明提升

/**********************
var n  //变量声明被提升至顶部
*********************/
console.log(n) // undefined(在这里可以读取到n的原因就在于变量声明提升)
var n = 123
function fn(){
    /*****变量声明被提升至顶部******
    var n  
    *************************/
    console.log(n) //undefined(在这里可以读取到n的原因就在于变量声明提升)
    var n = 456
    console.log(n)
}
fn()

示例: 模拟函数提升

/********整个函数被提升到顶部**********
function fn(){
  console.log('hello world')
}           
*******************************/
fn() // 'hello world' (在这里可以读取到fn()的原因就在于函数提升)
function fn(){
  console.log('hello world')
}

函数声明也会创建变量,所以函数声明也会发生变量提升,与变量声明提升不同的是,整个函数,包括函数声明与函数体都会被提升至当前作用域顶部。

函数也是数据

在JavaScript中,函数实际上也是一种数据。这种特殊的数据类型由两个重要特性:

  • 它们包含的是语句
  • 它们是可执行的

既然函数是一种数据类型。也就是说,我们可以把一个函数赋值给一个变量。
这是创建函数的第二种方法叫做:函数表达式。创建函数表达式的语法是:

函数定义表达式

var myFunction = function name([param[, param[, ... param]]]) { statements }

示例

//定义函数
var fn = function(a,b){
  return a + b
}
//调用函数
fn(2,3) //5

函数表达式和函数声明其实是不同的,两者的差别表现在它们所在的上下文。函数声明只会出现在程序代码里。

使用函数思想写程序的思路

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

推荐阅读更多精彩内容

  • 本文档内容参考 《JavaScript 闯关记》之函数 函数是一段代码,它只定义一次,但可以被执行或调用任意次。在...
    穿越人海遇见你阅读 1,003评论 0 1
  • 函数是Python里组织代码的最小单元,Python函数包含以下几个部分: 定义函数 调用函数 参数 函数的返回值...
    职场亮哥阅读 422评论 0 0
  • 前一篇文章,用一天的时间,通过与 JavaScript 做对比的方式,快速领略了 Python 全貌。 梳理了那么...
    Jeremy_young阅读 776评论 0 1
  • 对于编程语言而言,函数是不可或缺的一块内容。因为在编写代码的过程中,不可避免会出现很多重复、冗余的代码,从而导致代...
    LouisDrink阅读 639评论 0 1
  • @[toc] 1. 三元运算 1.1 语法结构 1.2 三元运算示例 ① 让用户输入一个值,如果值是整数,则转换成...
    Erics1996阅读 450评论 0 0