通过一道面试题对闭包,this指向问题加深理解

//js  
var x = 1;

        var obj = {

            x: 2

        }

        obj.fn = (function (x) {

            this.x *= x++;

            return function (y) {

                x += y;

                this.x *= ++x;

                console.log(x);

            }

        })(obj.x);

        var fn = obj.fn; 

        obj.fn(2);

        fn(1);

        console.log(obj.x, x);

在解决问题之前,先复习一下几个概念,其中涉及闭包,高阶函数,立即执行函数,this的指向问题

闭包:指内部函数对外部函数的变量进行了访问。

高阶函数:指的是将函数作为参数或者返回值进行传递。

立即执行函数:指的是在函数执行时,立即执行,如(function)()。

this指向问题,在单纯的函数调用中,函数中的this指向全局,即window;当对象调用方法时,this指向的是该实例对象。

 

理清楚了这些概念之后,开始分析题目

 

1.变量的声明:

  Window.x = 1 , obj.x = 2

 

2.立即执行函数

指的是(function(x))(obj.x)

变量的变化:

传入的参数是obj.x,即形参x = 2;

全局变量this.x =window.x = window.x *(x++)=2

形参 x = 3

return funtion(y),只是作为返回值,并没有进行计算

 

3.Var fn = obj.fn;

在这一步中只是将fn赋值

 

4.Obj.fn(2)

注意这里是对象调用方法,所以fn里面的this指向的是obj ,即 this.x = obj.x;

同时存在内部函数对外部函数的调用,形成了闭包,注意形参x的值得变化

执行函数:

function (y) {

                x += y;

                this.x *= ++x;

                console.log(x);

            }

 

传入参数 y =2,

在这里并没有传入x值,所以向外部函数访问,得到 X = 3;

形参 X = X+ y = 3+2=5

This.x = obj.x = obj.x * (++x) = 2 *6 = 12;

即目前 obj.x = 12, 形参x = 6

在这里打印出来的形参console.log(x) 结果为6

 

5. fn(1)

在这里是单纯的函数调用,this指向的是window

所以,传入参数 y = 1;

同第四步,这里产生了闭包,即形参x = 6

形参x = x+y=6+1 = 7;

Window.x在第二步变成2之后,直到现在没有改变

(全局变量)This.x = window.x *(++x) = 2 * 8 = 16

此时因为(++x)形参x = 8;

所以打印出来的形参console.log(x) 结果为8

 

6 .  console.log(obj.x,x)

在变量中查找,obj.x = 12 ,全局变量x =16

表达不当之后,欢迎大家指正!

 

 

 

你可能感兴趣的:(总结,面试题,javascript,函数闭包)