JavaScript_函数

本文详细介绍了JavaScript中的函数,包括4种定义方式:具名函数、匿名函数、ES6箭头函数和Function构造函数。讨论了函数的调用、形参和实参、参数可以是另一个函数的情况。重点讲解了函数的返回值、调用时机、提升(hoisting)以及作用域(scope)的概念和规则,包括作用域链、闭包以及异步函数的调用时机。此外,还提到了let的“提升”现象和解决循环中计时器问题的方法。
摘要由CSDN通过智能技术生成

什么是函数

预先定义好内容并可以在特定时机执行的一段代码。

对象的键也可以对应一个函数。此时这个函数一般叫方法。

函数的4种定义方式

具名函数

也称显式函数。语法:

function 函数名(形参1, 形参2, ...){语句}

function add(a,b){
   
	return a+b
}

显式函数赋给变量,通过变量调用不会出错但是通过函数名调用时会报错。

//显式函数赋给变量,通过变量调用不会出错但是通过函数名调用时会报错。
let a = function add(a,b){
   
	return a+b
}
a(1,2) //3
add(1,2) //报错,add未被定义。

匿名函数

也称函数表达式。将函数赋给一个变量,函数本身没有自己的名字。

let a = function(a,b){
   
	return a+b
}

[ES6]箭头函数

ES6提供的简化函数写法的方式。

语法:

(参数1,...) => {语句}

如果函数的参数只有1个,小括号可以省略。

如果函数只有1句执行语句,且该语句执行后返回一个非对象字面量,大括号可以省略,以该值作为返回值。

let a = (a,b) => a + b

如果只有1句语句,且该语句执行后返回一个对象字面量,需要在该对象上加上小括号。

let a = (a,b) => ({
   "1":a, "2":b})

Function()构建

语法:

Function("形参1", "形参2", ..., "语句")

形参和语句都必须加上引号。

基本没什么用。可以提醒我们所有函数都是Function函数构造的。

let a = Function('a','b','return a+b')

调用函数

如何调用函数

JS中的函数写好之后不会立即执行(除非是立即执行函数),只有在调用时才会执行。

调用函数的方法很简单,语法是显式函数的名字(参数1,...)匿名函数对应的变量(参数1,...)

即使一个函数不需要参数,调用时括号也是必不可少。如果不写括号,使用的是函数的内存地址。

function sayHi(){
   
	console.log("Hello!")
}
sayHi //ƒ sayHi(){console.log("Hello!")}
sayHi() //Hello!

形参和实参

函数声明时写的参数叫做形参,调用函数时传过来的参数叫实参。

//a和b是形参
function add(a,b){
   
	console.log(arguments)
}
//1和2是实参
add(1,2)

调用时,实参会一一复制给形参(还是浅拷贝),于是形参就可以在函数内部使用了。

//假设调用了add(1,2)
function add(a,b){
   
	//偷偷执行了let a = 1, let b = 2
	console.log(a, b) //1 2
}

实参可多可少

实参可以比形参多,多余的参数被忽略。

实参可以比形参少,没有实参的形参自动赋值undefined

function add(a,b){
   
	console.log(a,b)
}
add(1,2,3) // 1 2
add(1)// 1 undefined

获取实参

每个函数在调用时生成一个arguments对象,包含了本次调用传来的参数,可以在函数内部访问。无论实参比形参多还是少,传来几个参数就获得几个参数。

arguments是一个伪数组。

function add(a,b){
   
	console.log(arguments)
}
add(1,2)
/*
Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 1
1: 2
callee: ƒ add(a,b)
length: 2
Symbol(Symbol.iterator): ƒ values()
__proto__: Object
*/

函数的参数可以是另一个函数

之前提到数组有一个遍历方法forEach

它接受一个函数,这个函数有2个参数,分别表示元素和下标。

let a = [1,2,3]
a.forEach((item, index)=>{
   console.log(`${
     index}: ${
     item}`)})
/*
0: 1
1: 2
2: 3
*/

问题来了,为什么这个函数的参数分别能表示元素和下标?为什么顺序不是先下标后元素?

为了理解这个问题,我们自己实现一个myEach的方法模拟它:

//把该方法挂载到数组的原型上
Array.prototype.myEach = function(fn){
   
	//this默认指向该数组
	for(let i = 0; i < this.length; i++){
   
		//调用时还需要把数组本身传进去,特殊情况下有用。
		//函数中的函数
		//关键就在这里,这个函数里的前2个参数便是元素和下标。
		fn(this[i],i,this)
	}
}

let a = [1,2,3]
a.myEach((item, index)=>{
   console.log(`${
     index}: ${
     item}`)})

函数的返回值

所有函数都有返回值。想让一个函数返回一个指定的值的语法是return 表达式。如果不写,默认返回undefined。例如console.log("2")也有返回值undefined,打印出2不过是中间的一个步骤。

表达式1+2不是函数,因此它有,没有返回值。只有函数有返回值。

函数的调用时机

同一个函数在不同的位置调用,效果(很)可能不一样。

let a = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值