javascript的闭包和异步机制

javascript的闭包和异步机制

        javascript的闭包利用了javascript的作用域链和和活动对象(与C/C++这类静态语言不同,有点类似java这种动态语言)。异步机制则是在javascript的运行机制上的编程方式。

1、闭包

        a、活动对象:在一个函数的执行环境中(函数开辟的栈空间)用于存放函数的参数、变量、内部函数。

        b、实例

function createComparisonFunction(propertyName) {
	return function(object1, object2){
		var value1 = object1[propertyName];
		var value2 = object2[propertyName];
		if (value1 < value2){
			return -1;
		} else if (value1 > value2){
			return 1;
		} else {
			return 0;
		}
	};
}
//创建函数
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames({name:"Nicholas"},{name:"Greg"});
//解除对匿名函数的引用(用于释放内存)
compareNames = null;

         图解:当var compareNames=createComparisonFunction("name")时。

  

    当调返回compareNames的时候,会形成下面的内存模型(这也是闭包的内存模型)

javascript的闭包和异步机制_第1张图片

        当compareNames=null时,匿名函数作用链才会消失。

        ps:

            缺点:占用内存,请慎重使用。

            优点:

                    1、命名方便而且内存干净,不用将所有的变量挂载在window下

                    2、没有在 <闭包函数=null>之前,会一直存在内存中。可以当作一个缓存使用。

                    3、模拟一个class的封装。当我们var compareNames("name"); 的时候,我们就像在堆中创建了一个class的对象。而且、没运行一次都会重新分配一次内存,相会之间不会影响。

        c、测试

<!DOCTYPE html>
<html>
<head>
<script>
function createComparisonFunction(propertyName) {
	return function(object1, object2){
		var value1 = object1[propertyName];
		var value2 = object2[propertyName];
		if (value1 < value2){
			return -1;
		} else if (value1 > value2){
			return 1;
		} else {
			return 0;
		}
	};
}
//创建函数
var names = createComparisonFunction("name")({name:"Nicholas"},{name:"Greg"});
var ages = createComparisonFunction("age")({age:1},{age:3});
//调用函数
console.log(names);
console.log(ages);
//解除函数
names=null;
ages=null;
</script>
</head>
<body>
	闭包
</body>
</html>

         

  

2、异步机制

        总结:

            1、javascript是单线程的,所有的任务都会按顺序执行。

            2、为了在等待I/O设备的的信息时,利用CPU的运算能力。将任务分为同步任务(顺序执行)异步任务(任务放在一个任务队列中等待执行)。

            ps:比如C:从main()开始,我们都是一个函数一个函数的开辟栈,然后函数执行完成释放栈。最后释放main()栈。但是在javascript中把需要I/O等待的任务(function)直接放在了一个task queue中。当栈中的任务执行完成,栈空。就会从task queue中提取一个可以执行的任务,然后按顺序执行。知道栈和task queue上的任务都执行完。

        他们大概的区别像下面这种:

                   a、c的运行模型

javascript的闭包和异步机制_第2张图片

        c从main()开始,一直是随调用的函数在栈里面开辟帧,关闭帧。整体上是顺序执行的,如果遇见了I/O处理的函数只有等待。

            b、javascript的运行模型

javascript的闭包和异步机制_第3张图片

            javascript在C的模型基础上多了一个task queue(任务队列:存放任务链队列)。一个任务链(即执行顺序)执行成后,栈会空闲,然后从任务队列中重新取出一个可运行的任务链执行。在这其中只要含有异步方式的函数都会变成一个任务连放在任务队列中(例如 :I/O读取等待)。

            可运行的任务链:读取文件完成,setTime、setInterval的时间到达。

            一条任务链:如C的main()方法是任务链的开端。

        javascript的这种执行方式,优点就是CPU的执行效率高,缺点就是耗费内存,因为需要更多的空间来存放函数的上下文环境。

你可能感兴趣的:(JavaScript)