javascript中的this指向总结(一)

380 阅读3分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。

javascript中的this指向是十分重要的,同时也是难以理解。这次我对this的指向问题做个学习总结。

this的作用

我们创建一个对象,对象中有name属性和eating、running、studying方法,如果想要在这些方法中拿到name属性,我们就可以使用this,这里的this代表的是obj对象。

var obj = {
  name: 'haha',
  eating: function() {
    console.log(this.name + '在吃东西');
  },
  running: function() {
    console.log(this.name + '在跑步');
  },
  studying: function() {
    console.log(this.name + '在学习');
  }
}

obj.eating()
obj.running()
obj.studying()

那么我们不使用this可以在这方法中拿到obj对象的name属性吗?

  eating: function() {
    // console.log(this.name + '在吃东西');
    console.log(obj.name + '在吃东西');
  },
  running: function() {
    // console.log(this.name + '在跑步');
    console.log(obj.name + '在跑步');
  },
  studying: function() {
    // console.log(this.name + '在学习');
    console.log(obj.name + '在学习');
  }

我们可以通过obj.name获取到name属性。从某些角度来说,开发中如果没有this,很多问题我们也是有解决方案的。但是没有this,会让我们编写代码非常不方便。

我们新创建一个info对象,复制上面的代码,就需要把对象中的log中的obj改成info。这是相当的麻烦。

var info = {
  name: 'haha',
  eating: function() {
    console.log(info.name + '在吃东西');
  },
  running: function() {
    console.log(info.name + '在跑步');
  },
  studying: function() {
    console.log(info.name + '在学习');
  }
}

info.eating()
info.running()
info.studying()

但是有了this之后,我们只需要修改变量名就行,不需要修改对象中的内部代码。

var info = {
  name: 'haha',
  eating: function() {
    console.log(this.name + '在吃东西');
  },
  running: function() {
    console.log(this.name + '在跑步');
  },
  studying: function() {
    console.log(this.name + '在学习');
  }
}

info.eating()
info.running()
info.studying()

this的指向

this在全局作用域的指向

在全局作用域下,this指向根据运行环境的不同也会不同。在浏览器环境中,this指向的是window(globalObject)。在node环境中,this指向的是空对象{}。在node环境中,node执行js文件的时候会把这个文件当做一个模块module,然后加载这个模块。加载之后,会编译我们的代码,编译完之后,会把我们所有的代码放在一个函数中,然后执行这个函数.call({}),把this指向空对象{}。

我们在浏览器环境中执行以下代码。

console.log(this);
console.log(window);

我们可以看到浏览器环境中的this指向的是window。 image.png 我们在node环境中执行以下代码,在node环境中是没有window的。

console.log(this);

image.png

this在函数中的使用

我们通常在函数中使用this,很少直接在全局作用域下去使用this。

  • 所有函数在被调用时,都会创建一个函数执行上下文
  • 这个上下文中记录着函数的调用栈、AO对象等。
  • this也是其中的一条记录。 需要注意的是,this指向什么,跟函数所处的位置是没有关联的,但是跟函数被调用的方式是有关系。

我们可以通过不同的方式调用函数,this指向就不同。

function foo() {
  console.log(this);
}

// 1. 直接调用这个函数
foo()

// 2.创建一个对象,对象中的函数指向foo
var obj = {
  name: 'haha',
  foo: foo
}

obj.foo()

// 3. apply调用
foo.apply('abc')

我们在浏览器中运行以上代码,可以看到,定义一个函数,采用不用的方式对它进行调用,this会有不同的指向。 image.png 我们可以得出以下结论:

  • 函数在调用时,JavaScript会默认给this绑定一个值
  • this的绑定和函数定义的位置(编写的位置)没有关系
  • this的绑定和调用方式以及调用的位置有关系
  • this是动态绑定的,即是在运行时被绑定的