《Js》烦人的this指向

2021-01-04  本文已影响0人  BA_凌晨四点

首先要认清几个概念:

  1. 普通函数的调用方式
  2. 构造函数的调用方式
  3. 全局对象

在ES5之前,构造函数和普通函数的定义方式都是一样的:function 函数名(){},只不过构造函数名约定好是大写字母开头...

  1. 普通函数 的调用不用多说了吧。就是函数名字()
  2. 构造函数 的调用,可以通过关键字 new出来 对象的,就是new 函数名字()
  3. 全局对象: 在web端,全局对象是window;在node端,全局对象是global
  4. 函数的最后,如果没有写return,默认 return this

关键点来了

  1. 普通函数的调用
function demo() {
  console.log(this);
}
demo(); // this 指向 全局对象
  1. 构造函数的调用
function Demo() {
  console.log(this);
}
new Demo(); // this 指向 Demo

这里判断就是:调用函数的时候有没有new关键字。

  1. 如果有new,说明这是构造函数在构造一个对象。而this指向的是new出来的这个对象;
  2. 如果没有new,并且只是普通函数自己调用,this指向的是全局。

如果普通函数被别人调用?

var obj = {
    fn:function(){
        console.log(this);
    }
}
obj.fn();  // this 指向 obj

此时,fn这个函数算是被obj调用(因为fn执行之前有个小数点,这个小数点紧挨着的前面是谁,就算是被谁调用)

你学废了吗?

来一个稍微绕一点的。

var girl = {
    friend: {
        fn: function(){
            console.log(this); //window
        }
    }
}
var boy = girl.friend.fn; // 注意哦,这里并没有人要执行。看到有小括号才算执行:(),这里只是赋值操作
boy();

还是那句话,boy执行的时候:

  1. 先判断有没有new
  2. 判断前面没有小数点

所以this指向全局

再来

var girl = {}
function fn() {
  console.log(this);
}
girl.fn = new fn();  // this 指向 fn
console.log(girl.fn); // this 指向 fn

已经有new了,就不要关心前面的小数点了。

小结:

  1. 调用的时候有newthis 指向该对象。
  2. 调用的时候前面有小数点,this指向小数点前面紧挨着的那个对象

如果有了return:

function Demo() {
  console.log(this);
  return 123;
}
var res = new Demo(); // 此时函数已经执行了。this 指向 Demo。
console.log(res);  // 此时 this 依然指向 Demo
function Demo() {
  console.log(this);
  return {
      name: '李华'
  };
}
const res = new Demo(); // 此时函数已经执行了。this 指向 Demo。
console.log(res); // 此时,res 中的 this 指向 返回的对象

小结,如果函数最后有return:

  1. 如果return的是基本数据类型,接受者的this 指向跟之前说的一样。
  2. 如果return的是引用类型,接受者的this 指向return的这个数据。

注意一些情况啊:

function Demo() {
  console.log(this)
  this.skill = function () {
    console.log(this)
    return {};
  }
}
var res = new Demo().skill;
res();  // this 指向全局

虽然有new关键字,但看清楚,不是把 new 出来的这个对象交给 res,而是这个对象里面的方法。

PS:

  1. 严格模式下,函数自己调用,this 指向 undefined,不再指向 window 了
  2. ES6中有个叫做 箭头函数=>,它本身是不存在this的,它里面的this,取决于外层给它的
上一篇 下一篇

猜你喜欢

热点阅读