JS this指向

JS this指向

JS this指向

在JavaScript中,this是一个非常重要的关键字,它指向当前执行上下文中的一个对象。this的指向在不同情况下会有不同的值,导致初学者经常困惑。本文将详细解释this的指向及其常见用法。

全局上下文中的this

在全局上下文中,this指向全局对象,在浏览器中通常是window对象,在Node.js环境中则是global对象。示例代码如下:

console.log(this === window); // true

function test() {
  console.log(this === window); // true
}

test();

以上代码中,通过this === window的判断,可以证明this在全局上下文中指向window对象。

函数中的this

在函数中,this的指向会根据调用方式的不同而有所变化。主要有以下几种情况:

作为普通函数调用

当函数作为普通函数被调用时,this指向全局对象。示例代码如下:

function test() {
  console.log(this === window); // true
}

test();

在上面的示例中,test()函数被作为普通函数调用,此时this指向全局对象window

作为对象的方法调用

当函数作为对象的方法被调用时,this指向调用该方法的对象。示例代码如下:

let obj = {
  name: 'Alice',
  sayName: function() {
    console.log(this.name);
  }
};

obj.sayName(); // Alice

在上面的示例中,sayName方法被对象obj调用,所以this指向obj,输出Alice

构造函数中的this

当函数作为构造函数来调用时,this指向通过new关键字新创建的实例对象。示例代码如下:

function Person(name) {
  this.name = name;
}

let person1 = new Person('Bob');
console.log(person1.name); // Bob

在上面的示例中,Person函数被作为构造函数调用,通过new关键字创建了一个新的实例person1,此时this指向person1对象,最终输出Bob

箭头函数中的this

箭头函数是ES6新增的语法,它的this不会改变,而是根据外层(函数或全局)作用域来决定。因此,在箭头函数中使用this时要格外注意。示例代码如下:

let obj = {
  value: 123,
  getValue: function() {
    return () => {
      console.log(this.value);
    };
  }
};

let fn = obj.getValue();
fn(); // 123

在上面的示例中,getValue方法中返回了一个箭头函数,该箭头函数中使用了this,由于箭头函数没有自己的this,所以其this绑定在了外层的obj对象上,最终输出123

使用call、apply和bind改变this指向

JavaScript提供了callapplybind三个方法,可以临时改变函数中this的指向。

call和apply

callapply用于调用函数,第一个参数是要绑定的this对象,后续参数分别为函数的实参列表(apply要求参数为数组)。示例代码如下:

function sayName() {
  console.log(this.name);
}

let obj1 = { name: 'Tom' };
let obj2 = { name: 'Jerry' };

sayName.call(obj1); // Tom
sayName.apply(obj2); // Jerry

在上面的示例中,sayName函数使用callapply分别将this指向obj1obj2,最终输出TomJerry

bind

bind方法会创建一个新函数,将原函数中的this绑定为传入的对象,但并不立即执行新函数,而是返回一个绑定后的函数。示例代码如下:

function sayName() {
  console.log(this.name);
}

let obj = { name: 'Alice' };
let boundFn = sayName.bind(obj);

boundFn(); // Alice

在上面的示例中,sayName函数通过bind方法将this绑定为obj对象,并返回了一个新的函数boundFn,最终通过新函数调用来输出Alice

简单绑定与硬绑定

在某些场景下,我们希望永久地绑定函数中的this,此时可以使用硬绑定的方法来实现。示例代码如下:

function sayName() {
  console.log(this.name);
}

let obj = { name: 'Bob' };

let boundFn = sayName.bind(obj);
boundFn(); // Bob

let obj2 = { name: 'Alex' };
boundFn.call(obj2); // Bob

在上面的示例中,通过bind方法将this永久绑定为obj,即使通过call方法也无法改变this的指向。

箭头函数与普通函数this指向的对比

在箭头函数中,this的指向是静态的,它指向的是函数被创建时的上下文,而普通函数的this指向是动态的,它在函数被调用时确定。示例代码如下:

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

let obj = { name: 'Alice'};

test.call(obj); // Object { name: "Alice" }

let arrowFn = () => {
  console.log(this);
}

arrowFn.call(obj); // Object { name: "Alice" }

在普通函数中,通过callthis指向了obj对象;而在箭头函数中,虽然也使用了call,但this仍然指向了全局对象,这是因为箭头函数的this是静态的。

结语

this是JavaScript中的一个重要概念,它的指向在不同情况下有所不同,在实际开发中需要特别注意this的使用。通过本文的介绍,相信读者对this的指向及其应用已经有了更清晰的认识。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程