返回

js中this指向优先级的通透理解

前端

一个搞定js中的this指向优先级的方法:
思路整理与强化训练
{######封装专项元素开始######}

{######封装专项元素结束######}

在js中,this指向是一个复杂的话题,经常让开发者感到困惑。本文将通过一个简单的方法来帮助你理解和掌握js中this指向的优先级,让你对this指向有更深入的了解。

首先,我们需要了解js中this指向的几个基本概念:

  • 执行上下文: 每个js代码块都会创建一个执行上下文,执行上下文是一个包含变量对象、作用域链和this对象的容器。
  • 作用域: 作用域是变量和函数的可见范围,作用域链是从当前执行上下文到全局执行上下文的链。
  • this: this指向当前执行上下文的this对象。

那么,js中this指向的优先级是怎样的呢?

  1. 显式绑定: 使用bind()、call()或apply()方法显式绑定this指向。
  2. 隐式绑定: 函数在调用时,this指向默认绑定到函数所属的对象。
  3. 默认绑定: 如果函数既没有显式绑定也没有隐式绑定,那么this指向全局对象(在浏览器中是window对象)。

通常情况下,我们会使用显式绑定来控制this指向,因为显式绑定是最可靠的。隐式绑定可能会受到作用域的影响,而默认绑定则只在函数没有显式绑定和隐式绑定时才会使用。

现在,我们来看一个例子:

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('John');
person.sayHello(); // Hello, my name is John

在这个例子中,我们创建了一个Person类,并在其原型上定义了一个sayHello()方法。然后,我们创建了一个Person对象person,并调用sayHello()方法。

在sayHello()方法中,this指向person对象,因此console.log()会输出"Hello, my name is John"。

这是因为在调用sayHello()方法时,this隐式绑定到了person对象。

但是,如果我们使用bind()方法显式绑定this指向,那么this指向就会发生改变。

const person = new Person('John');
const sayHello = person.sayHello.bind(this);
sayHello(); // Hello, my name is undefined

在这个例子中,我们使用bind()方法将this指向绑定到了当前对象(即window对象)。因此,在调用sayHello()方法时,this指向window对象,console.log()会输出"Hello, my name is undefined"。

这是因为window对象没有name属性,因此console.log()输出undefined。

通过这个例子,我们可以看出显式绑定是如何改变this指向的。

显式绑定可以让我们更好地控制this指向,从而避免一些意外的错误。

除了显式绑定之外,我们还可以使用箭头函数来改变this指向。

箭头函数没有自己的this指向,它总是继承父级作用域的this指向。

const person = new Person('John');
const sayHello = () => {
  console.log(`Hello, my name is ${this.name}`);
};
sayHello(); // Hello, my name is undefined

在这个例子中,我们使用箭头函数定义了一个sayHello()函数。由于箭头函数没有自己的this指向,因此它继承了父级作用域的this指向,即window对象。

因此,在调用sayHello()方法时,this指向window对象,console.log()会输出"Hello, my name is undefined"。

通过这个例子,我们可以看出箭头函数是如何改变this指向的。

箭头函数可以让我们更方便地改变this指向,从而避免一些意外的错误。

js中this指向是一个复杂的话题,但只要我们掌握了基本的概念和用法,就能轻松应对各种this指向的问题。