javascript函数的运行的机制
2020-4-7
456

函数创建和执行的堆栈运行机制

function func() {
	let total = 10 + 10;
	console.log(total)
}
func();			//=>每执行一次会形成一个新的执行上下文
创建一个函数

1.创建值

  • 首先开辟一个堆内存
  • 把函数体中的代码当做字符串存储到堆中
  • 把堆地址放到栈中

2.创建变量

3.让变量和地址关联

]()

只创建函数,其实就是创建了一个存储一堆字符串的堆而已,并没有实际作用

执行一个函数

1.创建一个全新的执行上下文,把执行上下文压缩到栈内存中去执行(=>进栈执行)

2.在这个上下文中,也存在一个变量对象,用来存储当前上下文代码执行中所创建的变量

3.执行代码

4.当上下文中的代码都执行完后,如果该上下文中的信息没有被外面占用的情况,则执行完全出栈(以此减少栈内存中的空间)

return返回值
功能一
function func() {
	let total = 10 + 10;
	console.log(total)		// 20
	// return total
}
func();	
console.log(total)	//err->total is not defined

上面的代码,函数自上而下开始执行,创建一个函数,在栈中存储变量和堆地址,在堆中存储字符串;函数执行,在栈中开辟私有作用域,在私有作用域中执行方法,在私有作用域中,我们可以找到total,输出20。在全局作用域中输出total,会报错;这就是作用域的作用,私有作用域的变量只能是私有作用域中查找,全局变量对象中是没有total。

如果我们在私有作用域中把 私有作用域的total 变量返回出去,这样我们就可以在全部变量里面找到total了。这个就是return的作用。我们把这种在外部作用域可以拿到私有作用域变量的方法叫做闭包

在执行函数的时候,有这么一条规则:当上下文中的代码都执行完后,如果该上下文中的信息没有被外面占用的情况,则执行完全出栈(销毁当前作用域)。现在使用了return,func这个私有作用域的total被外部使用,那么这个私有作用域就会保留在执行环境栈ECStack中,占用内存。如果调用total变量的这个函数一直没有销毁,那么func这个私有作用就会一直保留,造成内存泄漏

功能二
function func(x){
    // 验证X是否为有效数字,如果不是,则不再继续执行后面的代码
	if(isNaN(x)){
		return
	}
    let result = x +1;
    return result
}

return在函数中,除了返回信息外,还有告知函数体中,下面的代码不再执行的作用