好家伙,本篇为《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函数一些基本概念的更多相关文章

  1. UI5-技术篇-JS函数eval动态执行

    <html lang="en"> <head> <meta charset="utf-8" /> <title> ...

  2. 学好js,这些js函数概念一定要知道

    函数创建方式 1.声明方式 例如:function consoleTip (){ console.log("tip!"); } 2.表达式方式 例如:var consoleTip ...

  3. 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  4. 如何编写高质量的 JS 函数(1) -- 敲山震虎篇

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ作者:杨昆 一千个读者,有一千个哈姆雷特. 此系列文 ...

  5. 如何编写高质量的 JS 函数(2) -- 命名/注释/鲁棒篇

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/sd2oX0Z_cMY8_GvFg8pO4Q作者:杨昆 上篇<如何编写高质量的 JS 函数 ...

  6. 如何编写高质量的 JS 函数(3) --函数式编程[理论篇]

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/EWSqZuujHIRyx8Eb2SSidQ作者:杨昆 [编写高质量函数系列]中, <如何 ...

  7. 如何编写高质量的 JS 函数(4) --函数式编程[实战篇]

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/ZoXYbjuezOWgNyJKmSQmTw作者:杨昆 [编写高质量函数系列],往期精彩内容: ...

  8. js函数与作用域,了解函数基本概念

    通过js基础语法了解到js的值包含数字,字符串和布尔值;js运算符分为算数,赋值,比较和逻辑运算符;js的流程控制包含条件判断if,switch选择;循环for while:下面js的函数及作用域,学 ...

  9. JS函数篇【2】

    什么是函数 函数的作用,可以写一次代码,然后反复地重用这个代码. <h3 onload="add2(1,2,3);add3(4,5,6)"></h3> &l ...

  10. AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX

    AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX 一.什么是JSX 使用JSX声明一个变量(REACT当中的元素): const element =< ...

随机推荐

  1. [转帖]OpenAI 道歉:Redis bug 致 ChatGPT 故障、数据泄露

    https://www.163.com/dy/article/I0N6HEIT0511D6RL.html OpenAI表示,Redis的开源库bug导致了发生在周一的ChatGPT故障和数据泄露事件, ...

  2. 是否开启超线程对CPU不同命令的影响情况

    背景 最近公司购买了一台服务器, 要进行一次性能测试. 基于此, 我这边进行了一下超线程与否的测试验证 使用stress-ng的命令,对所有的 CPU 方法进行测试 然后只分析 bogo ops/s ...

  3. 不想做架构师的Gopher不是好程序员

    最近我们在组队学习<手把手带你写一个web框架>,强制PUSH,坚持每天学习打卡,不完成惩罚发红包的那种. 你别说,效果还真挺好. 昨天学到了架构部分,很受启发,光学不写假把式.(还是得坚 ...

  4. Docker容器基础入门认知-Namespce

    在使用 docker 之前我一般都认为容器的技术应该和虚拟机应该差不多,和虚拟机的技术类似,但是事实上容器和虚拟机根本不是一回事. 虚拟机是将虚拟硬件.内核(即操作系统)以及用户空间打包在新虚拟机当中 ...

  5. echarts设置标题样式

    <!DOCTYPE html> <html> <!-- https://blog.csdn.net/weixin_42698255/article/details/892 ...

  6. go中异常处理流程

    在 Go 语言中,panic.recover 和 defer 是用于处理异常情况的关键字.它们通常一起使用来实现对程序错误的处理和恢复. 1. defer 语句 defer 用于在函数返回之前执行一段 ...

  7. OpenIM Open Source Instant Messaging Project Docker Compose Deployment Guide

    The deployment of OpenIM involves multiple components and supports various methods including source ...

  8. 期盼已久全平台支持-开源IM项目OpenIM之uniapp更新

    国内uniapp使用广泛,OpenIM的uniapp sdk以及文档和demo (https://github.com/OpenIMSDK/Open-IM-Uniapp-Demo)都已更新,本文主要展 ...

  9. 『Echarts』简介

    目录 一.前言 二.『Echarts』简介 1. 什么是『Echarts』 三.数据可视化 四.『Echarts』 1.『Echarts』的作用 2.『Echarts』能绘制哪些图表 3.『Echar ...

  10. JuiceFS v1.0 正式发布,首个面向生产环境的 LTS 版本

    今天,JuiceFS v1.0 发布了 经过了 18 个月的持续迭代和大量生产环境的广泛验证,此版本将成为第一个被长期维护的稳定版(LTS).同时,该版本提供完整的向前兼容,所有用户可以直接升级. J ...