JavaScript中this指向原理及改变方法详解

作者:小括号时间:2026-10-23 23:48:12浏览:167

本文深入解析JavaScript中this的动态指向机制,指出其取决于函数调用位置。详细对比了普通函数与箭头函数在this绑定上的差异,并介绍了通过call、apply和bind改变this指向的具体用法及代码示例。

JavaScript this指向原理与改变方法详解

在JavaScript学习过程中,this的指向问题常令初学者困惑。本文将系统梳理this的指向规则,并介绍改变this指向的几种常用方法。

this的指向机制

一、this的指向机制

理解this指向前,需明确两个核心概念:

1. this始终指向一个对象;

2. this的具体指向完全由函数被调用的位置决定;

第一点易于理解,因为JavaScript中万物皆对象。第二点表明,函数调用位置不同,this指向的对象也不同,这意味着this具有动态变换的特性。接下来通过一个简单示例观察this的动态变化。


<script>
function fun(){
   console.log(this.name);

 }
 var change={
   name:'hello',
   f:fun
 }
 var name ='world'
 var result=change.f()//hello
 fun();//world
</script>

上述示例清晰展示了this指向的变化。由于函数存在于对象change内部,此时this指向函数外部的对象,因此输出结果为hello。

通过上述示例,相信大家对this的动态指向切换已有一定了解。

常见this指向场景

接下来,我们对this使用最频繁的几种场景进行总结,最常见的基本包括以下3种:

对象中的方法、事件绑定、构造函数、定时器

前两种场景较为常见,此处重点分析定时器中的this指向问题。


var obj = {
  fun:function(){
    this ;
  }
}
​
setInterval(obj.fun,1000);   // this指向window对象
setInterval('obj.fun()',1000); // this指向obj对象

setInterval()是window对象下的内置方法,接收两个参数:第一个参数可以是函数或可执行的JS代码片段,第二个参数则是执行前者的时间间隔(毫秒)。

在上面的代码中,setInterval(obj.fun,1000)的第一个参数是obj对象的fun方法。由于JS中函数可作为值进行引用传递,实际是将该函数的地址作为参数传递给setInterval方法。换言之,setInterval接收了一个函数引用,1000毫秒后,该函数的运行环境已处于window对象下,即函数的调用者变为window对象,因此其中的this指向全局window对象。

而在setInterval('obj.fun()',1000)中,第一个参数实际传入的是一段可执行的JS代码字符串。1000毫秒后,当JS引擎执行这段代码时,是通过obj对象来查找并调用fun函数。此时函数的运行环境仍在对象obj内部,因此函数内部的this指向obj对象。

改变this指向的方法

除了上述情况,我们还需要掌握三个可以改变this指向的方法,包括箭头函数、call()和apply()。

箭头函数:官方解释指出,引入箭头函数的原因之一是其不绑定this。在箭头函数中,this被设置为封闭的词法环境的值,换言之,箭头函数中的this取决于该函数被创建时的环境。

var globalObject = this; var foo = (() => this); console.log(foo() === globalObject); // true // 接着上面的代码 // 作为对象的一个方法调用 var obj = {foo: foo}; console.log(obj.foo() === globalObject); // true // 尝试使用call来设定this console.log(foo.call(obj) === globalObject); // true // 尝试使用bind来设定this foo = foo.bind(obj); console.log(foo() === globalObject); // true

无论如何,foo的this被设置为其被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法环境的。


// 创建一个含有bar方法的obj对象,
// bar返回一个函数,
// 这个函数返回this,
// 这个返回的函数是以箭头函数创建的,
// 所以它的this被永久绑定到了它外层函数的this。
// bar的值可以在调用中设置,这反过来又设置了返回函数的值。
var obj = {
 bar: function() {
  var x = (() => this);
  return x;
 }
};

// 作为obj对象的一个方法来调用bar,把它的this绑定到obj。
// 将返回的函数的引用赋值给fn。
var fn = obj.bar();

// 直接调用fn而不设置this,
// 通常(即不使用箭头函数的情况)默认为全局对象
// 若在严格模式则为undefined
console.log(fn() === obj); // true

// 但是注意,如果你只是引用obj的方法,
// 而没有调用它
var fn2 = obj.bar;
// 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。
console.log(fn2()() == window); // true

call和apply方法:将一个对象作为call或者apply的第一个参数,this将会被绑定到这个参数对象上。


var obj = {parent:'男'};
var parent = '28';
function child(obj){
  console.log(this.parent);
}
child(); // 28 
child.call(obj); //男
child.apply(obj); //男

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章