当前位置: 首页 > article >正文

函数声明与函数表达式

函数声明

一个标准的函数声明,由关键字function 、函数名、形参和代码块组成。

有名字的函数又叫具名函数

举个例子:

function quack(num) {
for (var i = 0; i < num; i++) {
    console.log("Quack!")
  }
}
quack(3)

函数表达式

函数没有名称,而且位于一条赋值语句右边,被赋给一个变量。

在语句(如赋值语句)中,以这样的方式使用关键function时,创建的是函数表达式。

没有名称的函数又叫匿名函数

举个例子:

var fly = function(num) {
    for (var i = 0; i < num; i++) {
	console.log("Flying!");
    }
}
fly(3)

下面是一个关于如何区分函数声明和函数表达式的简单提示:

如果语句以function关键字开头,那么它就是一个函数声明,否则就是一个函数表达式。

(当function关键字在表达式中创建一个函数(有或没有名称)时,才是一个函数表达式。)

// 函数声明: 以 `function` 关键字开头
function sumA(a, b) {
  return a + b;
}

// 函数表达式: 不以 `function` 关键字开头
const mySum = (function sumB(a, b) {
  return a + b;
});

// 函数表达式: 不以 `function` 关键字开头
[1, 2, 3].reduce(function sum3(acc, number) { 
  return acc + number 
});


// 函数表达式

const sum = (function sumB(a, b) {
  return a + b;
});

// 函数表达式
const myObject = {
  myMethod: function() {
    return 42;
  }
};

// 函数表达式
const numbers = [4, 1, 6];
numbers.forEach(function callback(number) {
  console.log(number);
  // logs 4
  // logs 1
  // logs 1
});

在函数表达式中创建的函数有两种:

  1. 如果表达式内的函数没有名称,例如function() {return 42},则这是一个匿名函数表达式;
  2. 如果函数有名字,例如前面例子中的sumBcallback,那么这就是一个命名函数表达式

从更高的角度来看,函数声明对于创建独立的函数很有用,但是函数表达式作为回调很好。

现在,让我们深入了解函数声明和函数表达式的行为。

乍一看,函数声明和函数表达式差别不大,但实际上它们存在根本性差别。

要明白这种差别,首先需要研究一下浏览器在运行阶段如何处理代码。

举个例子,看看浏览器如何分析并执行网页中的代码。

var migrating = true;
var fly = function (num) {
  for (var i = 0; i < num; i++) {
      console.log("Flying!")
  }
}

function quack(num) {
  for (var i = 0; i < num; i++) {
      console.log("Quack!")
  }
}

if (migrating) {
  quack(4)
  fly(4)
}

分析浏览器如何执行代码

第一步:分析函数声明

在分析网页期间(执行任何代码之前),浏览器查找函数声明。找到函数声明时,浏览器创建相应的函数,并将得到的函数引用赋给与函数同名的变量。

第二步:浏览器执行代码

处理所有的函数声明后,浏览器回到代码开头,开始按从头到尾的顺序执行代码。

 

第三步:继续执行

处理完变量fly后,浏览器继续往下执行。接下来的语句是函数quack的声明,因为已经处理过了,所以浏览器跳过声明,接着执行后面的条件语句。

小结一下,浏览器的执行过程:

  1. 首先扫描代码,查找函数声明
  2. 分析函数声明(存储该函数,并创建一个与函数同名变量来存储指向该函数的引用)
  3. 处理完所有函数声明后,浏览器从头开始执行代码(按顺序处理各种函数变量)
  4. 碰到函数表达式时,同函数声明,需存储该函数,并将指向该函数的引用赋给表达式左边的变量

结论:函数声明与函数表达式的区别

函数声明函数表达式
1函数声明是完整的语句函数表达式只是语句的一部分
2函数命名时,创建一个与函数同名的变量,并让它指向函数函数命名时,通常不给函数指定名称,因此需要在代码中将函数赋给一个变量,或以其他方式使用函数表达式
3可以出现在代码的任何地方,函数声明创建的函数都是自己定义的,这被称为提升(hoisting)函数表达式创建的函数要等到它执行后才被定义
4函数将在执行代码前创建,即使未调用,也占用内存空间函数将在运行阶段执行代码时临时创建,调用完,立即释放,所以更节省内存空间

讲了这么多,相信你对函数声明与函数表达式已经有了一定的了解,来做个题目试试水吧~

阅读以下代码,从上到下依次说出执行结果:

// 从上到下依次说出执行结果
var foo = function () {
    console.log("foo1")
}
foo()

var foo = function () {
    console.log("foo2")
}
foo()


function foo() {
    console.log("foo1")
}
foo()

function foo() {
    console.log("foo2")
}
foo()

具体答案,见下篇文章解答吧~

引用文章:

一个例子讲清楚函数声明和函数表达式 - 知乎


http://www.kler.cn/news/148042.html

相关文章:

  • uniapp之Vue3配置跨域(代理)
  • [RK-Linux] recovery分区详解(二)
  • harmonyos应用开发者高级认证考试部分答案
  • 配置ssh 免密登录 还是要密码才能登录
  • 二次开发问题汇总【C#】
  • MySQL进阶-InnoDB引擎
  • 全新付费进群系统源码 完整版教程
  • 数字人对本地生活商家的影响和应用
  • 竞赛选题 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测
  • Rust语言入门教程(五) - 流控制语句
  • vue 中 js 金额数字转中文
  • 其利天下技术总监冯建武受邀出席“2023年电子工程师大会”并作主题演讲
  • 【精选】框架初探篇之——MyBatis的CRUD及配置文件
  • Linux - 系统调用(syscall)
  • Qt实现绘制自定义形状
  • ORACLE 多实例监听的配置
  • 接收网络包的过程——从硬件网卡解析到IP层
  • jar包不挂断地运行命令
  • 【电路笔记】-电源电压
  • 时间复杂度和运算
  • lack——主页前后端开发优化(精华:java多线程实现数据插入)
  • 【docker】docker的基础命令
  • 消失的数字,旋转数组(leetcode 一题多解)
  • 力扣 hot100 最小覆盖子串 滑动窗口 字符计数
  • 【沁恒蓝牙mesh】CH58x 将RTC时钟切换为LSE外部低速时钟
  • 中年人怎么发展?持续发展?
  • 牛客 算法 HJ103 Redraiment的走法 golang语言实现
  • 【brpc学习实践九】mbvar及bvar可观测
  • Web语言基础课程期末代做
  • 【git】pip install git+https://github.com/xxx/xxx替换成本地下载编译安装解决网络超时问题