强大的this你了解多少?

219 阅读4分钟

简介this:

this 是 JavaScript 中的一个关键字,代表当前执行代码所在的对象。它的值根据执行上下文的不同而变化。在 JavaScript 中,this 的行为是动态的,而不是静态的,这意味着它的值是在运行时确定的,而不是在编写代码时确定的。

this的作用

this的值根据V8执行的上下文不同而改变,this可以显著的提升代码质量,减少上下文参数的传递,让代码优雅化,具体如下:

  1. 指向当前对象:当函数作为对象的方法被调用时,this 指向调用该方法的对象,这样函数可以访问和操作该对象的属性和方法。
const person = {
  name: 'John',
  greet: function() {
    console.log('Hello, ' + this.name);
  }
};

person.greet(); // 输出 "Hello, John"
  1. 实现方法的重用:通过 this,可以将函数定义为通用的方法,然后在不同的对象上调用,实现对不同对象的操作,从而提高代码的重用性。
function greet() {
  console.log('Hello, ' + this.name);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

greet.call(person1); // 输出 "Hello, Alice"
greet.call(person2); // 输出 "Hello, Bob"

  1. 构造函数中的对象初始化:在构造函数中,this 指向通过 new 关键字创建的新对象,可以使用 this 在对象初始化时设置对象的属性。
function Person(name) {
  this.name = name;
}

const person = new Person('Alice');
console.log(person.name); // 输出 "Alice"

  1. 明确函数调用的上下文:通过显式地绑定 this,可以确保函数在调用时具有特定的上下文,而不受调用位置的影响。
const obj1 = { name: 'Alice' };
const obj2 = { name: 'Bob' };

function greet() {
  console.log('Hello, ' + this.name);
}

const greetAlice = greet.bind(obj1);
const greetBob = greet.bind(obj2);

greetAlice(); // 输出 "Hello, Alice"
greetBob(); // 输出 "Hello, Bob"

  1. 事件处理:在处理 DOM 事件时,this 经常用于指向触发事件的 DOM 元素,从而可以在事件处理函数中访问和操作该元素。
<button id="myButton">Click me</button>

<script>
document.getElementById('myButton').addEventListener('click', function() {
  console.log('Button clicked by: ' + this.id);
});
</script>

以上是this的一些作用需要了解。

this 的绑定规则

默认绑定:当一个函数独立调用,不带任何修饰符的时候。

也就是说:函数在哪个词法作用域下生效,函数中的this就指向哪里。

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

function bar() {
  foo()
}

function baz() {
  bar()
}

baz()

foo的调用虽然在bar的作用域内,但是foo仍是自己独立的调用,所以说foo在全局作用域下调用,所以this指向window,打印结果所示:

image.png

2. 隐式绑定:当函数的引用有上下文对象的时(当函数被某个对象所拥有时)-函数的this指向引用它的对象

var obj = {
  a: 1,
  foo: foo
}

var obj2 = {
  a: 2,
  obj: obj
}

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

obj2.obj.foo()

obj2.obj.foo() 的调用下,打印出this所指向的对象,这里foo并没有独立调用,而是在 foo: foo 下进行引用【定义foo在传入foo变量,到foo的执行】,此时this直接指向引用它的对象也就是obj,访问到 a = 1,打印并非是undefined。

这里为什么不是2? 插入一下:隐式丢失:当一个函数被多个对象链式调用时,函数的this指向就近的那个对象,仍是obj为大不是obj2。

显示绑定:call apply bind

var obj = {
    a: 1
}

function foo(x, y) {      
    console.log(this.a, x + y);
}

// foo.call(obj, 2, 3)

// foo.apply(obj, [1, 2])

var bar = foo.bind(obj, 3, 4)
bar(2)

分别用call,apply,bind的显示绑定,使this.a弯曲到obj下访问里面的值。【记住即可】

注意: 这里传参有区别:

  1. call:后面直接零散传参
  2. apply:后面需要中括号[]来传参
  3. bind:可以直接零散传参,也可以在引用后面传参

new 绑定: this指向创建的实例对象

function Person() {
    
    this.name = 'Jack'    
}
let p = new Person()   // 实例对象
let p2 = new Person() 

这里P直接到函数Person中,让this指向P这个实例对象中。

箭头函数没有this这个机制,写在箭头函数中的this也是它外层非箭头函数的this

function foo() {

}

function foo() {
  var bar = () => {
    console.log(this);
  }
  bar()
}
foo()

在这个箭头函数中没有this这个机制,所以this是在foo函数中,访问全局作用域,打印出window。

总结:

this的绑定规则就是如此,记住好各个结构也就能自己运用自如的让this代表自己所想要指向的对象。

希望能帮到大家,顺便支持一下长安

image.png