和this来一场旅途吧!

290 阅读4分钟

this定义

关于this的定义,参考MDN上面的描述述是这样的:在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同

this的值

他是指当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。

同时,this在严格模式和非严格模式之间也会有一些差别。this的指向也一直是我们关注的话题。而且也是我们通常不能理解的地方,让我们来认真的了解一下this

注意!!! 无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

不同场景下this的指向

严格模式下:浏览器和node下都是undefined;浏览器环境下: 20210821112036.png

node环境下:

function fun(){
    "use strict"; // 这里是严格模式
    return this
}
console.log(fun() === undefined); //true

在严格模式下,假设进入执行环境没有设置this的值,this会保持为undefined,fun()被直接调用,不是作为对象的属性或者方法调用。

在非严格模式下:this 的值默认指向全局对象,浏览器中就是 window

构造函数中的this

当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。 我们先啊哟记住构造函数中的一些特点: 虽然构造函数返回的默认值是 this 所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 this 对象)。

举个例子:

function Person(){
    this.name='tdl'
}
let p = new Person()
console.log(p.name); //tdl

function Person2(){
    this.name ='tdl'
    return {name:'小谭'}
}
let p2 = new Person2()
console.log(p2.name); // 小谭

通俗一点来说:当函数具有返回对象的return语句时该对象是new表达式的结果 否则,表达式的结果是当前绑定到this的对象

因为Person()中没有返回对象,所以他的this就是指向创建该对象的实例,所以就会让p.name为tdl,而在Person2()中,因为在调用构造函数的过程中,我们通过手动的设置了返回对象,所以导致与this绑定的默认对象被丢弃了,此时this就是指向return返回的对象,所以就有这样的结果p.name为小谭

对象方法中的this

当函数作为对象里的方法被调用时,this 被设置为调用该函数的对象。this 的绑定只受最接近的成员引用的影响。

var obj = {
    name: "tdl",
    foo: function () {
        return this.name;
    }
};
console.log(obj.foo()); //tdl

当obj.foo()被调用是,this指向obj

改变代码如下时:

var obj = {
    name: "tdl",
    sayName:{
        foo: function () {
            return this.name;
        }
    }
};
console.log(obj.sayName.foo()); //undefined

上面代码的this指向的是obj.sayName ,而不是在指向obj了

var obj = {
    name: "tdl",
    sayName:{
        foo: function () {
            return this.hi;
        },
        hi:'hello'
    }
};
console.log(obj.sayName.foo()); //hello

修改sayName里面的内容,结果输出 hello这就可以判断this指向sayName

在 ES5 中,其实this 的指向可以这样概括:this 永远指向最后调用它的那个对象 最后调用它的对象

箭头函数中的this

this代表的是该函数的词法作用域中的this(函数定义的位置), 并且指向最后调用的对象 因为箭头函数没自己的执行上下文, 所以箭头函数的里面this就是它外层函数执行上下文的this

在这里严格模式下不是输出undefined,

var f = () => { 'use strict'; return this; };
f() === window; // 或者 global
function Person(){
    this.age = 1;
    setInterval(() => {
      this.age++; //正确地指向 p 实例
    }, 1000);
  }
  
  var p = new Person();
  console.log(p.age); //1

箭头函数没有单独的this,箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同

总结:

  • 无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。
  • 在函数内部,this的值取决于函数被调用的方式。
  • 严格模式下,如果进入执行环境时没有设置 this 的值,this 会保持为 undefined
  • 构造函数中,this绑定的是新创建的对象。
  • 箭头函数,箭头函数的this继承的是外层代码块的this。

参考文献 MDN 以及婧大的博客:blog.csdn.net/qq_45678607… 制作不易,希望看到这里的小伙伴们加油鼓励一下! 感谢观看!