好家伙,本篇为《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. 使用perfdog如何测试微信小程序

    测试微信小程序和测试其他app唯一的不同点是如何在app中选中要测试的小程序 至于其他的基本操作可查看https://www.cnblogs.com/lihongtaoya/p/15140610.ht ...

  2. VScode中下载了插件但是无法找到SSH Target连接服务器的解决方法(CANNOT find SSH Target in remote explorer)

    VSCode版本vscode version:(version 1.82) 已下载扩展installed extensions: Remote - SSH v0.106.4 Remote - SSH: ...

  3. vuex标准化看这篇文章就够了~

    1.新建一个store文件夹,新建index.js文件,内容如下: import Vue from 'vue' import Vuex from 'vuex' import state from '. ...

  4. JS 逆向之 Hook,吃着火锅唱着歌,突然就被麻匪劫了!

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 什么是 Hook? Hook 中文译为钩子,Hook 实际上是 Windows 中提供的一种用以 ...

  5. 在Unity中使用SQLite保存配置表数据(For Lua)

    在Lua中使用sqlite Lua版本Sqlite文档:http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki sqlite官网:https ...

  6. Object.getOwnPropertyDescriptor()属性

    console.log(Object.getOwnPropertyDescriptor(person,'a')); // writable: 是否可以修改 // value: 对象值 // confi ...

  7. C++11之函数对象

    目录 1.使用场景 2.函数对象 3.std::bind 4.总结 1.使用场景 在没有C++11的时候,我们通常使用回调函数来完成某些特定的功能,使用回调函数就需要先声明函数指针 示例: typed ...

  8. Tauri VS. Electron - 真实项目的比较

    文章翻译自:Tauri VS. Electron - Real world application 以下是正文: 在这篇文章中我将会用真实的项目来比较 Electron 和 Tauri: Authme ...

  9. 7、后端学习规划:PHP学习 - 学习规划系列文章

    PHP在其阵营中被称为世界上最好的编程语言.笔者在学习了其一些框架后也有一定的经验,当时主要根据其框架进行的开发.对于PHP来说,在编程排行榜上也是有名的存在,现在还有一些网站应用也是用的PHP进行的 ...

  10. 常用TS总结

    自己常用的 TS 写法总结,应该会一直更新.可使用 TS在线编译 校验 TS 语法. 基本用法 普通 const num: number = 10 const isStop: boolean = fa ...