第122篇: JS函数一些基本概念
好家伙,本篇为《JS高级程序设计》第十章“函数”学习笔记
1.函数的三种定义方式:函数表达式、函数声明及箭头函数
函数声明:
function sum(a) {
return a + 1;
}
函数表达式:
let sum= function(a){
return a + 1;
}
箭头函数:
let sum = (a) => {
return a + 1;
}
以函数声明方式声明的函数存在"函数声明提升",
在执行代码时,JavaScript 引擎会先执行一遍扫描, 把发现的函数声明提升到源代码树的顶部。
因此即使函数定义出现在调用它们的代码之后,引擎也会把 函数声明提升到顶部。
而函数表达式这么做会报错(箭头函数同样报错)

代码如果没有执行到函数表达式的那一行,那么执行上下文中就没有函数的定义
2.函数名
函数名是指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。
function sum(num1, num2) {
return num1 + num2;
}
console.log(sum(10, 10)); // 20
let anotherSum = sum;
console.log(anotherSum(10, 10)); // 20
sum = null;
console.log(anotherSum(10, 10)); // 20
以上代码定义了一个名为 sum()的函数,用于求两个数之和。
然后又声明了一个变量 anotherSum, 并将它的值设置为等于 sum。
注意,使用不带括号的函数名会访问函数指针,而不会执行函数。
此时, anotherSum 和 sum 都指向同一个函数。
调用 anotherSum()也可以返回结果。把 sum 设置为 null 之后,就切断了它与函数之间的关联。
而 anotherSum()还是可以照常调用,没有问题。(有意思,之前不清楚)
ECMAScript 6 的所有函数对象都会暴露一个只读的 name 属性,其中包含关于函数的信息。
多数情 况下,这个属性中保存的就是一个函数标识符,或者说是一个字符串化的变量名。
即使函数没有名称, 也会如实显示成空字符串。
function AAA(){}
let BBB =function (){}
let CCC =()=>{}
console.log(AAA.name);
console.log(BBB.name);
console.log(CCC.name);
console.log((()=>{}).name);

(最后一行有东西的,空字符)
3.参数
ECMAScript 函数的参数跟大多数其他语言不同。
ECMAScript 函数既不关心传入的参数个数,也不 关心这些参数的数据类型。
定义函数时要接收两个参数,并不意味着调用时就传两个参数。
你可以传一 个、三个,甚至一个也不传,解释器都不会报错。(好家伙)
4.没有重载
js没有重载
(这可真是太有意思了,方法名是指针,参数不管数量,我想js自然是不会有重载的)
方法后定义覆盖先定义(记住了,要考的)
function add(num) {
return num + 100;
}
function add(num) {
return num + 200;
}
let result = add(100); // 300
显然,定义两个同名参数,后定义的会覆盖先定义的
5.arguments属性
arguments 是一个类数组对象,包含调用函数时传入的所有参数。
function test(a,b,c,d,e){
console.log(arguments)
}
test(1,2,3,4);

5.1.arguments.callee
arguments 对象其实还有一个 callee 属性,是一个指向 arguments 对象所在函数的 指针。
想不出什么好的例子,就用书中的原例吧:
(书中原例)
一个阶乘递归
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
随后用arguments.callee代替factorial
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
这时候可能有人会问了,这有什么屌用.我刚开始也是这么想的,后来又看了两遍,发现js开发者还是有点东西的
使用 arguments.callee 就可以让函数逻辑与函数名解耦
我们接着看:
(重要的一个例子)
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
let trueFactorial = factorial;
factorial = function () {
return 0;
};
console.log(trueFactorial(5)); // 120
console.log(factorial(5)); // 0

这段就有意思了,
trueFactorial 变量被赋值为 factorial,所以console.log(trueFactorial(5));结果为120;
但是console.log(factorial(5)); 结果又为0;
trueFactorial 不受factorial方法重写的影响
这一个例子就帮我们记住了三个知识点:
1.函数名真的是指针
2.使用 arguments.callee 就可以让函数逻辑与函数名解耦
3.js有重写,莫得重载
6.caller属性
caller属性引用的是调用当前函数的函数,或者如果是 在全局作用域中调用的则为 null。
function outer() {
inner();
}
function inner() {
console.log(arguments.callee.caller);
}
outer();

第122篇: JS函数一些基本概念的更多相关文章
- UI5-技术篇-JS函数eval动态执行
<html lang="en"> <head> <meta charset="utf-8" /> <title> ...
- 学好js,这些js函数概念一定要知道
函数创建方式 1.声明方式 例如:function consoleTip (){ console.log("tip!"); } 2.表达式方式 例如:var consoleTip ...
- 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...
- 如何编写高质量的 JS 函数(1) -- 敲山震虎篇
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ作者:杨昆 一千个读者,有一千个哈姆雷特. 此系列文 ...
- 如何编写高质量的 JS 函数(2) -- 命名/注释/鲁棒篇
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/sd2oX0Z_cMY8_GvFg8pO4Q作者:杨昆 上篇<如何编写高质量的 JS 函数 ...
- 如何编写高质量的 JS 函数(3) --函数式编程[理论篇]
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/EWSqZuujHIRyx8Eb2SSidQ作者:杨昆 [编写高质量函数系列]中, <如何 ...
- 如何编写高质量的 JS 函数(4) --函数式编程[实战篇]
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ZoXYbjuezOWgNyJKmSQmTw作者:杨昆 [编写高质量函数系列],往期精彩内容: ...
- js函数与作用域,了解函数基本概念
通过js基础语法了解到js的值包含数字,字符串和布尔值;js运算符分为算数,赋值,比较和逻辑运算符;js的流程控制包含条件判断if,switch选择;循环for while:下面js的函数及作用域,学 ...
- JS函数篇【2】
什么是函数 函数的作用,可以写一次代码,然后反复地重用这个代码. <h3 onload="add2(1,2,3);add3(4,5,6)"></h3> &l ...
- AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX
AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX 一.什么是JSX 使用JSX声明一个变量(REACT当中的元素): const element =< ...
随机推荐
- [转帖]OpenAI 道歉:Redis bug 致 ChatGPT 故障、数据泄露
https://www.163.com/dy/article/I0N6HEIT0511D6RL.html OpenAI表示,Redis的开源库bug导致了发生在周一的ChatGPT故障和数据泄露事件, ...
- 是否开启超线程对CPU不同命令的影响情况
背景 最近公司购买了一台服务器, 要进行一次性能测试. 基于此, 我这边进行了一下超线程与否的测试验证 使用stress-ng的命令,对所有的 CPU 方法进行测试 然后只分析 bogo ops/s ...
- 不想做架构师的Gopher不是好程序员
最近我们在组队学习<手把手带你写一个web框架>,强制PUSH,坚持每天学习打卡,不完成惩罚发红包的那种. 你别说,效果还真挺好. 昨天学到了架构部分,很受启发,光学不写假把式.(还是得坚 ...
- Docker容器基础入门认知-Namespce
在使用 docker 之前我一般都认为容器的技术应该和虚拟机应该差不多,和虚拟机的技术类似,但是事实上容器和虚拟机根本不是一回事. 虚拟机是将虚拟硬件.内核(即操作系统)以及用户空间打包在新虚拟机当中 ...
- echarts设置标题样式
<!DOCTYPE html> <html> <!-- https://blog.csdn.net/weixin_42698255/article/details/892 ...
- go中异常处理流程
在 Go 语言中,panic.recover 和 defer 是用于处理异常情况的关键字.它们通常一起使用来实现对程序错误的处理和恢复. 1. defer 语句 defer 用于在函数返回之前执行一段 ...
- OpenIM Open Source Instant Messaging Project Docker Compose Deployment Guide
The deployment of OpenIM involves multiple components and supports various methods including source ...
- 期盼已久全平台支持-开源IM项目OpenIM之uniapp更新
国内uniapp使用广泛,OpenIM的uniapp sdk以及文档和demo (https://github.com/OpenIMSDK/Open-IM-Uniapp-Demo)都已更新,本文主要展 ...
- 『Echarts』简介
目录 一.前言 二.『Echarts』简介 1. 什么是『Echarts』 三.数据可视化 四.『Echarts』 1.『Echarts』的作用 2.『Echarts』能绘制哪些图表 3.『Echar ...
- JuiceFS v1.0 正式发布,首个面向生产环境的 LTS 版本
今天,JuiceFS v1.0 发布了 经过了 18 个月的持续迭代和大量生产环境的广泛验证,此版本将成为第一个被长期维护的稳定版(LTS).同时,该版本提供完整的向前兼容,所有用户可以直接升级. J ...