学习JavaScript函数需要知道的要素

如果想要弄懂函数下面这些东西你必须要弄懂!

目录:

1 调用时机
2.1 作用域
2.2 作用域的规则
2.3 !来给代码加点料
3.1 形式参数
3.2 来给代码加点料
4  返回值
5 调用栈
6 函数提升
7 立即执行函数
7.1 !来给代码加点料

1 调用时机

一个函数在调用的时机不同,那么它执行出来的结果也不同。

  • 来举个栗子
let a = 1
function fn(){
  console.log(a)
}
fn()

通过以上代码我们可以很容易的看出来最后执行fn()的时候打印出出1。我们接下里再提升一点难度,请看下方代码。

let a = 1
function fn(){
  console.log(a)
}
a = 2
fn()

这回大家猜猜看执行最后一句fn()的时候会打印出多少?肯定是打印出2的,至于为什么呢,当然是在执行到第5句的时候a = 2,在这个时候a已经不再是当初的a了因为a被重新赋值a = 2了。就这么简单。

  • 来!难度升级
elt a = 1
function fn (){
	setTimeout(()=>{
  	console.log(a)
  },0)
}
fn()
a = 2

细心的小伙伴可能已经看出来了这一切,这里我们多了一句setTimeout,setTimeout的意思就是稍后执行,稍后执行是什么意思呢?稍后,就是当前任务执行完再执行。也就是代码执行完了之后再执行打印,说以最后打印出2。


2 作用域

每个函数都会默认创建一个作用域。

  • 老规矩 举个栗子
function fn(){
	let a = 1
}
console.log(a)

执行这段代码我们会得到一个‘a’不纯在,就算fn执行了也访问不到作用域里面的‘a’。因为‘a’的作用域在花括号里面。‘let’的作用域非常的好找,往前找一个正的花括号,往后找一个反的花括号,这两个花括号之间就是它的作用域。出了这个空间它就不纯在。

2.1 作用域的规则

  • 如果多个作用域有同名变量a

那么查找a的声明时,就就向上取最近的作用域。简称“就近原则”。

查找a的过程与函数无关,但是a的值与函数执行有关。

 

2.2 !来给代码加点料

上面有讲到作用域(局部变量)现在在来讲讲全局变量

在顶级的作用域声明的变量是全局变量,window的属性是全局变量,其他的都是局部变量

  • 全局变量
function f2(){
	window.c = 2
  let b
}
f2()

function f1(){
	console.log(c)
}
f1()

通过以上代码我们可以看出,在f1里面打印f2里面的东西依然可以。这就是因为window是一个全局属性,把c挂到了window上面,c就自动的变成了一个全局变量。这就是为什么Object可以直接用,因为他是window.Object,parseInt也是如此,parseInt是window.parseInt。


3 形式参数

形式参数的意思就是非实际参数。

function add(){
	return x+y
}
add(1,2)

3.1 !来给代码加点料

形式参数就只是给代码取一个名字而已,里面的内容可多可少。

4 返回值

每一个参数都有返回值,不存在没有返回值的函数。

  • 少废话,举例子!
function hi(){
	console.log('hi')
}
hi()

看了以上代码有的小可爱可能就会问了,上面代码不是没有写return嘛。注意!没有写return返回值就是undefined。返回值是在执行之后才会出现的,你不执行就不存在所谓的返回值。

4.1 !来给代码加点料

function hi(){
	return console.log('hi')
}
hi()

看看以上代码返回值是多少?返回值为undefined。

看到没返回值是不是undefined,至于那个hi嘛,那个是打印值,返回值是返回值,打印值是打印值。

函数执行完了之后才会有返回值,也自有函数才有返回值。


5 调用栈

JS引擎在调用一个函数之前,需要把函数所在的环境push到一个数组里面去,这个数组就叫做调用栈。等函数执行完,就会把环境弹出(pop)出来,然后return到之前的环境,继续执行代码。

也就是说在调用一个函数的时候,我们需要到另外一个环境去执行它,执行完了之后再返回回来。函数是进到一个函数之后再返回回来,是这么个模型。

这个时候我们要是进入一个函数再进入一个函数再再进入一个函数,这是需要返回的时候函数就懵逼了,它不知道该返回哪里了。所以调用栈的作用就是进入以后函数之后该返回哪里。

当进入一个函数的时候需要把一个函数地址先存进来,存得多了就需要一个数组来保存,保存函数所在的环境就叫调用栈。


6 函数提升

  • 什么是函数提升

在使用“function fn(){}” 的时候不管你把具名函数声明在哪里,它都会跑到第一行。

  • 什么不是函数提升

在使用“let fn = function(){}”的时候,这是赋值,右边的匿名函数声明不会提升。

7 立即执行函数

在我们需要局部变量的时候,又不想要全局函数的时候就可以用到它。

  • 先来举个栗子
function fn(){
	var a = 1
}

这里我们通过了一个函数来声明一个局部变量,的确局部变量的目的达到了,但是!又多了一个函数fn全局变量。

聪明的小朋友可能就会想到,我直接创建一个匿名函数,后面直接调用不就可以了嘛,来我们看一下结果。

看到没!报错了,因为JS认为这个语法是错的。

但是如果在这个语法前面加上一个“操作符”就是对的,怎么加?看下面栗子!

+ function (){
	var a = 1
  console.log(a)
} ()

在语法前面加上一个操作符,问题就解决了。JS会先声明一个匿名函数,再执行这个匿名函数。由于这个匿名函数没有retunr所以返回值是NaN,但是我们并不关心它返回什么,我们只在意局部变量。

7.1 !来给代码加点料

在上个语法当中我们加操作符“+”“-”“1”或者“1*”都可以,但是单独一个“*”就不行,只需要做一个运算就可以。注意!最建议使用“!”

​新版JS创建一个局部变量最简单!

{
  let a = 1
  console.log(1)
}

看到没,新版js创建一个局部函数就这么简单,直接两个花括号就解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值