JavaScript的this问题?

var num = 20;

var obj = {
    num :30,
    fn:(function (num) {
        this.num *=3;
        num+=15;
        var num = 45;
        return function () {
            this.num*=4;
            num+=20;
            console.log(num);
        }
    })(num)
};
obj.fn();
fn执行的之后,这里面的this把我搞晕了?求大神解释一下。
好像如果变成var fn = obj.fn;fn();这样,this又会变
阅读 3.9k
5 个回答
var num = 20;  //声明全局变量num = 20
var obj = {
    num :30,    //声明对象属性num:30 
    fn:(function (num) {    //函数会创建独立的作用域,因此这里传入的num为全局变量中的num 
        this.num *=3;  //this指向的是window的        
        num+=15;    //参数num,即全局变量传入的20 
        var num = 45;   //对局部变量进行声明,参数优先,因此不会变量提升 
        return function () {
            this.num*=4;    //你所说的this会变,其实是指这里的this
            num+=20;    //num为局部变量 
            console.log(num);    //打印num的值   
        }
    })(num)
};
obj.fn();

this的指向总是指向调用者,因为IIFE的调用者是window,所以上面的第一个this不会改变,第二个this取决于你调用的方式,如果采用obj.fn();这种方式,则this指向obj; 如果采用var fn = obj.fn;fn();这种方式,相当于window.fn();this指向window

this的值执行时才能确定,定义时无法确认。常见以下几种场景:

  1. 普通函数(全局上下文):window
  2. 构造函数中: 新创建的对象
  3. 对象的方法中:调用该函数的对象
  4. 通过 call, apply, bind 指定
  5. 箭头函数:执行环境上下文的this
  6. dom事件中是 currentTarget,即事件处理函数绑定的元素

var num = 20;
var obj = {
    num :30,
    fn:(function (num) {// 20,不解释
        // this是场景1中的window
        // this.num = window.num = 20
        this.num *=3;// 执行后,window.num = 60
        num+=15;// 当前函数作用域里的参数 num = 20 + 15 = 35
        var num = 45;// 覆盖参数 num,num此时从 35 变成 45
        return function () {
            // 返回的函数在执行之前,this不确定
            // obj.fn()时,this为场景3,即obj
            // var fn = obj.fn;fn();时,this为场景1,即window
            this.num*=4;
            num+=20;// 父作用域中的num,num = 45 + (执行次数)*20
            console.log(num);
        }
    })(num)// 20,不解释
};
obj.fn();// 会将 obj.num *= 4
var fn = obj.fn;fn();// 等价于 obj.fn.call(window),会将window.num *= 4

在里面加上'debugger;'进行逐步跟踪执行顺序,就知道this了。
this要么是window 要么是obj。

var num = 20;
var obj = {
    num :30,
    fn:(function (num) {
        debugger;
        this.num *=3;
        num+=15;
        var num = 45;
        return function () {
            debugger;
            this.num*=4;
            num+=20;
            console.log(num);
        }
    })(num)
};
obj.fn();

首先程序先执行这个自执行函数 里面第一个this是window,第二个this 程序不会走到那儿。

fn:(function (num) {
        this.num *=3;
        num+=15;
        var num = 45;
        return function () {
            this.num*=4;
            num+=20;
            console.log(num);
        }
    })(num)

然后执行obj.fn(); 这个里面的this是 obj
//------------
如果变成var fn = obj.fn;fn();这样,里面this是window。

num传进去的是全局作用域里面的num即20,之后,又一次声明了num=45,所以最后打印出num的值就是65,num与this.num是不一样的。

做赋值以后代码执行环境变了,这时候的this指向window,并且还创建了一个undefined的num变量

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题