js | 改变this的指向

214 阅读1分钟

三种情况:

// 情况一
(obj.foo = obj.foo)() // window
// 情况二
(false || obj.foo)() // window
// 情况三
(1, obj.foo)() // window

分析: obj.foo就是一个值。这个值真正调用的时候,运行环境已经不是obj了,而是全局环境,所以this不再指向obj

简述: JavaScript 引擎内部,obj和obj.foo储存在两个内存地址,称为地址一和地址二。obj.foo()这样调用时,是从地址一调用地址二,因此地址二的运行环境是地址一,this指向obj。但是,上面三种情况,都是直接取出地址二进行调用,这样的话,运行环境就是全局环境,因此this指向全局环境

例子:

// 情况一
(obj.foo = function () {
  console.log(this);
})()
// 等同于
(function () {
  console.log(this);
})()

// 情况二
(false || function () {
  console.log(this);
})()

// 情况三
(1, function () {
  console.log(this);
})()

除此之外:

嵌套对象内部的方法赋值给一个变量,this依然会指向全局对象

    var a = {
        b: {
            m: function () {
                console.log(this.p);
            },
            p: "hello"
        }
    };

    var hello = a.b.m;
    hello() //undefined

    var a = {
        b: {
            m: function () {
                console.log(this.p);
            },
            p: "hello"
        }
    }
    var hello = a.b;
    hello.m(); //hello

解析: 将其赋值给hello变量,结果调用时,this指向了顶层对象。为了避免这个问题,可以只将m所在的对象赋值给hello,这样调用时,this的指向就不会变

回顾:

使用箭头函数

    var a = {
        b: {
            m: ()=> {
                console.log(this.p);
            },
            p: "hello"
        }
    }
    var hello = a.b;
    hello.m(); //undefined

解析请看此时不能使用箭头函数