简介this:
this
是 JavaScript 中的一个关键字,代表当前执行代码所在的对象。它的值根据执行上下文的不同而变化。在 JavaScript 中,this
的行为是动态的,而不是静态的,这意味着它的值是在运行时确定的,而不是在编写代码时确定的。
this的作用
this的值根据V8执行的上下文不同而改变,this可以显著的提升代码质量,减少上下文参数的传递,让代码优雅化,具体如下:
- 指向当前对象:当函数作为对象的方法被调用时,
this
指向调用该方法的对象,这样函数可以访问和操作该对象的属性和方法。
const person = {
name: 'John',
greet: function() {
console.log('Hello, ' + this.name);
}
};
person.greet(); // 输出 "Hello, John"
- 实现方法的重用:通过
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"
- 构造函数中的对象初始化:在构造函数中,
this
指向通过new
关键字创建的新对象,可以使用this
在对象初始化时设置对象的属性。
function Person(name) {
this.name = name;
}
const person = new Person('Alice');
console.log(person.name); // 输出 "Alice"
- 明确函数调用的上下文:通过显式地绑定
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"
- 事件处理:在处理 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,打印结果所示:
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下访问里面的值。【记住即可】
注意: 这里传参有区别:
- call:后面直接零散传参
- apply:后面需要中括号[]来传参
- 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代表自己所想要指向的对象。
希望能帮到大家,顺便支持一下长安