函数 作为 JS 的一等公民,随处可见它的身影。

我理解的它最主要作用就是用来提取重复代码,但凡有 JS 代码需要复制粘贴的时候,那么这时候就可以考虑使用函数封装了。

当函数写在对象中的时候,这时候它变了一个名字,称之为 方法

function 声明

在使用 function 关键字声明函数时,需注意声明提升问题,意思就是 function 声明的函数,不存在先后顺序,任意位置都可以调用。

function test() {
console.log('前端路引');
}
test() // 调用函数

test 就是函数的名字,函数名的规则和变量声明差不多,只要不是数字和特殊字符开头,语法规则都是允许的,包括都可以使用中文定义函数,虽然不建议这么使用!

function 测试() {
console.log('前端路引');
}
测试() // 调用函数

声明提升

function 定义的函数会提升到作用域顶部,所以可以在函数定义之前调用,比如:

test() // 此处可以调用 function 声明的函数

const var1 = '前端路引 -- 1'
console.log(var1) function test() {
console.log('前端路引 -- 2');
}

输出:

前端路引 -- 2
前端路引 -- 1

包括写在 if 判断中的 function 都会提升到作用域顶部,比如:

test()
if (false) {
console.log('前端路引 -- 1'); // 此行代码不会执行
function test() {
console.log('前端路引 --2');
}
}

输出:

前端路引 -- 2

所以不建议在条件语句中去使用 function 声明函数!

函数表达式

函数表达式就是使用一个变量来保存函数,这种写法有个好处是可以控制定义函数的逻辑。

声明方式:

const test = function() {
console.log('前端路引');
}
test()

表达式声明的函数只能在声明之后调用,如果在声明之前调用,代码会报错:

test() // 报错 ReferenceError: test is not defined
const test = function() {
console.log('前端路引');
}

使用 var 声明时会报错 TypeError: test is not a function:

test() // 报错 TypeError: test is not a function
var test = function() {
console.log('前端路引');
}

在 if 中声明的函数表达式,在外部无法调用:

if (false) {
const test = function() {
console.log('前端路引');
}
}
test() // 报错 ReferenceError: test is not defined

箭头函数

箭头函数的声明与函数表达式有些相似,都需要通过变量保存。

声明方式:

const test1 = () => {
console.log('前端路引');
}
const test2 = (a, b) => a + b; // 单行时候可以省略花括号,直接返回值
// 等价于
// const test2 = (a, b) => {return a + b}
test1() // 输出:前端路引
console.log(test2(1, 2)) // 输出:3

箭头函数和函数表达式的区别:

  • 箭头函数自身没有 this 绑定,继承外层作用域的 this
const test1 = function () {
console.log(this)
}
const test2 = () => {
console.log(this)
}
test1.bind({a: '123'})() // 获得对象 {a: '123'}
test2.bind({a: '123'})() // 获得全局对象 window
  • 由于没有 this,所以也无法作为构造函数使用,不能使用 new 实例化。
const test1 = function () {
console.log('前端路引')
}
const test2 = () => {
console.log('前端路引')
}
new test1()
new test2() // 报错 TypeError: test2 is not a constructor
  • 箭头函数也没有 arguments 对象,所以无法通过 arguments 相关方法,比如 arguments.callee 获取函数自身。
const test1 = function () {
console.log(arguments) // 获取到参数对象
}
const test2 = () => {
console.log(arguments) // 报错 ReferenceError: arguments is not defined
}
test1('前端路引')
test2('前端路引')

生成器函数

ES6 新增的声明方式,常规的业务代码一般很少使用(也可能是我的段位太低~~)。

function* test() {
yield 1;
yield 2;
}
const temp = test()
console.log(temp.next()) // 输出:{value: 1, done: false}
console.log(temp.next()) // 输出:{value: 2, done: false}
console.log(temp.next()) // 输出:{value: undefined, done: true}

这种方式可以使用 yield 暂停函数执行,多用于异步迭代场景。

看一个异步使用 yield 例子:

function* testAsync() {
const data = yield new Promise(resolve => {
setTimeout(() => resolve('Hello World'), 1000); // 模拟异步操作
});
console.log(data); // 此处的 data 是 next 传入数据,不是 Promise 返回数据
} async function run() {
const generator = testAsync();
const result = await generator.next().value; // 等待 Promise
generator.next(result); // 将结果传递回生成器并继续执行
}
run()

构造函数 Function 声明

虽然不建议使用这种声明函数,咱们学习了解一下还是没问题的。

const test = new Function('a', 'b', 'return a + b');
console.log(test(1, 2))

问题:

1、通过字符串动态生成代码,存在安全风险,容易出现代码注入攻击。

2、每次都会解析字符串,性能会比较低。

写在最后

函数 作为 JS 语言中的一等公民,几种声明方式区别是面试中的常客,经常被问及 箭头函数function 有哪些区别。

函数 是基础,也是函数式编程的核心,必须熟练掌握~~

Web前端入门第 64 问:JavaScript 几种函数定义方式有什么区别?的更多相关文章

  1. Javascript和JQuery函数定义方式

    Javascript 函数定义方式 1.function show() {     } 2.var cal = function() {     },必须先声明才能调用 示例: <html> ...

  2. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  3. Android零基础入门第64节:揭开RecyclerView庐山真面目

    原文:Android零基础入门第64节:揭开RecyclerView庐山真面目 大家还记得之前在第38期~第50期都在学习列表控件吗,其中用了8期讲ListView的使用,相信都已经掌握好了吧.那么本 ...

  4. web前端关于html转义符的常用js函数

    web前端关于html转义符的常用js函数 //去掉html标签 function removeHtmlTab(tab) { return tab.replace(/<[^<>]+? ...

  5. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  6. web前端(13)—— 了解JavaScript,JavaScript的引入方式

    从本篇博文开始,将进入web前端方便最关键最重要的部分——javascript,学到后面你就知道它真的太重要了 什么是JavaScript JavaScript一种直译式的脚本语言,是一种动态类型.弱 ...

  7. WEB前端工程师整理的原生JavaScript经典百例

    一.原生JavaScript实现字符串长度截取 二.原生JavaScript获取域名主机 三.原生JavaScript转义html标签 四.原生JavaScript时间日期格式替换 Date.prot ...

  8. Web前端基础怎么学? JavaScript、html、css知识架构图

    以前开发者只要掌握 HTML.CSS.JavaScript 三驾马车就能胜任一份前端的工作了.而现在除了普通的编码以外,还要考虑如何性能优化,如何跨端.跨平台实现功能,尤其是 AI.5G 技术的来临, ...

  9. web前端学习之HTML CSS/javascript之一

    前端编码之路之坎坷,web前端应该一直是个战场吧,各种浏览器的不兼容,各种小细节的修改,要往一个好的产品经理方向走,实在是难,昨天听了一位十年经验的产品经理讲座,最重要的恐怕就是协调资源的能力,而协调 ...

  10. web前端学习(四)JavaScript学习笔记部分(3)-- JavaScript函数+异常处理+事件处理

    1.Javascript函数-了解函数的用途 1.1.函数: 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块 2.Javascript函数-定义函数 2.1.function必须小写 3. ...

随机推荐

  1. Grafana导入 json 文件的 dashboard 错误 Templating Failed to upgrade legacy queries Datasource xxx not found

    前言 编辑或者修改后的 dashboard 保存为 json 文件,在其他环境导入使用,报错 Failed to upgrade legacy queries Datasource xxxxxxx w ...

  2. go time包:秒、毫秒、纳秒时间戳输出

    时间戳 10 位数的是以 秒 为单位: 13 位数的是以 毫秒 为单位: 19 位数的是以 纳秒 为单位: golang 中可以这样写: package main import ( "fmt ...

  3. 高德地图api标记点和线段重合点击响应问题

    问题现象: 现在地图上放置了line和marker,marker在line的上层显示 这时line和marker同时存在,当line和marker有重合部分并点击重合点时,只响应line对应的clic ...

  4. HTTP 和 RPC

    TCP 是传输层的协议,而基于 TCP 造出来的 HTTP 和各类 RPC 协议,它们都只是定义了不同消息格式的应用层协议而已. RPC(Remote Procedure Call),又叫做远程过程调 ...

  5. AI与.NET技术实操系列(九):总结篇 ── 探讨.NET 开发 AI 生态:工具、库与未来趋势

    1. 引言 本文作为本系列的最后一篇,旨在全面探讨 .NET 生态中与 AI 相关的工具.库.框架和资源,帮助开发者了解如何在 .NET 环境中开发 AI 应用.我们将分析 Microsoft 的 A ...

  6. 【JUC】基础总结

    多线程的思考:为什么需要run()和start()方法,只用其中一个不行吗? run()和start() run()是运行的时候就直接执行所有代码 start()相当于开启线程,并发执行,让这些线程开 ...

  7. 【Python】批量导出word文档中的图片、嵌入式文件

    Python 批量导出word文档中的图片.嵌入式文件 需求 学生试卷中的题目有要提交截图的,也有要提交文件的,为了方便学生考试,允许单独交或者嵌入Word中提交,那么事后如何整理学生的答案?单独提交 ...

  8. win11开启hyper-v安装windows虚拟机

    序言: 这周要居家办公了, 趁周末赶紧配置办公环境,因为公司注重安全保密,所以要用对应安全软件,我就干脆整台虚拟机来运行这些东西吧. 开启hyper-v服务 好像是由于电脑装的是windows家庭版, ...

  9. PyInstaller 常用用法

    PyInstaller 常用用法 PyInstaller 是一个跨平台的 Python 应用打包工具,支持 Windows/Linux/MacOS 三大主流平台,能够把 Python 脚本及其所在的 ...

  10. java程序乱码问题

    1.字符编码简介 字符编码从字面上理解,就是将字符编码为由多个bits(0或1)组成的字节序列.但字符和字节序列的映射并不是直接的,可简要概括为2个步骤,第1步由字符映射到unicode码,第2步由u ...