第122篇: JS函数一些基本概念

js,函数,一些,基本概念 · 浏览次数 : 83

小编点评

**函数的三种定义方式** 1. **函数表达式**: 函数表达式是函数定义的直接表达式,它包含一个函数声明和一对括号内的代码。 ```javascript let sum = function(a) { return a + 1; }; ``` 2. **函数声明**: 函数声明是使用关键字 `function` 定义函数的语法。 ```javascript function sum(num1, num2) { return num1 + num2; } ``` 3. **箭头函数函数声明**: 箭头函数函数声明是使用关键字 `function` 定义函数的语法,但它只包含一个表达式。 ```javascript let sum = (a) => { return a + 1; }; ``` **函数名** 函数名是指向函数的指针,它跟其他包含对象指针的变量具有相同的行为。 **参数** 在定义函数时要接收两个参数,并不意味着调用时就传两个参数。 **重载** 没有重载js没有重载(这可真是太有意思了,方法名是指针,参数不管数量,我想js自然是不会有重载的)方法后定义覆盖先定义的  **arguments**属性 `arguments` 是一个类数组对象,包含调用函数时传入的所有参数。 **例子** ```javascript // 阶乘递归function factorial(num) { // if (num <= 1) { // return 1; // } else { // return num * factorial(num - 1); // } // } // 使用arguments.callee 代替factorial函数 let trueFactorial = factorial; factorial = function () { return 0; }; console.log(trueFactorial(5)); // 120 console.log(factorial(5)); // 0 ```

正文

好家伙,本篇为《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函数一些基本概念相似的内容:

第122篇: JS函数一些基本概念

好家伙,本篇为《JS高级程序设计》第十章“函数”学习笔记 1.函数的三种定义方式:函数表达式、函数声明及箭头函数 函数声明: function sum(a) { return a + 1; } 函数表达式: let sum= function(a){ return a + 1; } 箭头函数: le

第一百一十四篇: JS数组Array(三)数组常用方法

好家伙,本篇为《JS高级程序设计》第六章“集合引用类型”学习笔记 1.数组的复制和填充 批量复制方法 copyWithin(),以及填充数组方法fill()。 这两个方法的函数签名类似,都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引。 使用这个方法不会改变数组的大小。 1.1.fi

零代码,让业务人员实现应用创造自由

摘要:以汽车营销场景为例,从AppCube零代码和业务大屏入手,帮助开发者更好地理解AppCube低代码和零代码异同点,在实际使用时能更快选取更合适的工具能力,实现应用构建效率最大化。 本文分享自华为云社区《DTT第8期直播回顾 | 零代码,让业务人员实现应用创造自由》,作者:华为云社区精选 。 本

第一百零五篇:变量的原始值和引用值

好家伙,JS基础接着学, 本篇内容为《JS高级程序设计》第四章学习笔记 1.原始值和引用值 ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值(primitive value)就是最简单的数据,引用值(reference value)则是由多个值构成的对象。 在把一个值赋给变

第一百零六篇:变量的不同声明(var,let和const的不同)

JS关于变量的声明,变量提升,暂时性死区

第一百零七篇:基本数据类型(undefined,null,boolean类型)

好家伙, 本篇内容为《JS高级程序设计》第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Number, String和Symbol。 Symbol (符号)是ECMAScript6新增的。还有一种复杂数据类型

第一百零八篇:最常用的基本数据类型(Number类型)

最常用的基本数据类型(Number类型)

第一百一十篇:内存泄漏和垃圾回收(JS)

好家伙,本篇内容为《JS高级程序设计》第四章的学习笔记 1.内存泄露 1.1.什么是内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 内存泄漏缺陷具有隐蔽性、积累性的特征,比其

第一百一十一篇:基本引用类型Date

好家伙,本篇为《JS高级程序设计》第五章的学习笔记 1.基本引用类型 引用值(或者对象)是某个特定引用类型的实例,在ECMAScript中,引用类型是把数据和功能组织到一起的结构,(像极了“类”) 经常被人错误的称作“类”。 虽然从技术上讲JavaScript是一门面向对象语言,但是ECMAScri

第一百一十二篇: JS数组Array(一)数组基本用法

好家伙, 1.数组 Array应该就是ECMAScript中最常用的类型了。ECMAScript数组跟其他编程语言的数组有很大区别。 跟其他语言中的数组一样,ECMAScript 数组也是一组有序的数据, 但跟其他语言不同的是,数组中每个槽位可以存储任意类型的数据。 这意味着可以创建一个数组,它的第