JavaScript回调函数、作用域、变量提升

阅读() @2018-10-29 18:16:04

今天,一个小伙伴遇到了问题:执行一个函数,说出最后这个函数的执行结果。代码如下:

(function(callback){
    president = {name:"bush"};
    callback(president);
    console.log(president.name);
})(function(a){
    a.name="obama";
    a = {name:"clinton"};
}); 

分析以上代码,可以得出以下结论:

1、第一个匿名函数定义的同时就执行,并且带有一个形参callback;

2、函数中定义了一个全局变量president,是一个json对象。

3、第二个匿名函数就是形参callback的实参;

4、第二个匿名函数中在执行的时候,它的参数又调用了第一个函数中的president。

为了方便理解,这个函数最后可以变形为:

 

(function(){
    president = {name:"bush"};
    function callback(){
    	var a = president;
	    a.name="obama";
	    a = {name:"clinton"};
	}
	callback(president);
    console.log(president.name);//obama
})();

其实,给一个函数传递实参,可以理解在在函数内部定义了一个局部变量,这个局部变量就是形参,它的值就是那个实参,就像以上代码var a = president一样。

那么打印president.name的时候,因为这个president所在作用域是外部函数的匿名函数,所以callback函数内部的变量是访问不到的,但是callback内部通过变量a可以访问到外部匿名函数的变量president,动态改变它的name值为obama,所以最后的打印结果是obama。

如果想要最后的打印结果是clinton,那么代码可以修改如下:

(function(){
    president = {name:"bush"};
    var a;
    function callback(){
    	a = president;
	    a.name="obama";
	    a = {name:"clinton"};
	}
	callback(president);
    console.log(a.name);
})();

推荐阅读:关于javascript执行顺序、变量提升、作用域的问题

JavaScript面试题(闭包+作用域+变量提升

JavaScript中闭包结合for循环的使用

微信二维码