一、this
是什么?
this
是一个指向对象的指针,指向函数执行上下文的引用对象。
二、this
的常见情况 (谁调用函数,this 就指向谁)
1. 全局上下文中的 this
当我们在全局作用域中使用 this
时,this
指向 全局对象。
在浏览器中,this
会指向 window
对象;在 Node.js 环境中,this
会指向 global
对象。
示例:
console.log(this); // 在浏览器中输出 window 对象
2. 普通函数中的 this
在普通的函数调用中,this
的值取决于函数是如何被调用的。如果函数是在全局作用域中调用的,那么 this
会指向全局对象(在浏览器中是 window
,在 Node.js 中是 global
)。如果函数是通过对象的方法调用的,this
会指向那个对象。
示例 1:全局函数调用
function show() {
console.log(this); // 在浏览器中,this 会指向 window
}
show();
示例 2:对象方法调用
const person = {
name: 'John',
greet: function() {
console.log(this.name);
}
};
person.greet(); // 输出 'John',this 指向 person 对象
三、this的特殊情况
3. 构造函数中的 this
当使用构造函数创建对象时,this
会指向新创建的实例对象。
示例:
function Person(name, age) {
this.name = name;
this.age = age;
}
const john = new Person('John', 30);
console.log(john.name); // 输出 'John'
console.log(john.age); // 输出 30
在这个例子中,this
在 Person
构造函数中指向的是新创建的 john
对象。
4. 事件处理中的 this
在事件处理程序中,this
通常指向 触发事件的 DOM 元素。
实例:
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this); // 在事件处理函数中,this 指向触发事件的 DOM 元素
});
this
是一个指向函数执行上下文的引用对象。
在这个例子中,this
指向的是 button
元素本身。
5. 箭头函数中的 this
箭头函数和普通函数有一个重要的区别:箭头函数 没有自己的 this
,它会从外部作用域 “继承” this
。
箭头函数的 this
是在函数创建时确定的,通常是它被定义时的上下文中的 this
。
示例:
const person = {
name: 'Jane',
greet: function() {
setTimeout(() => {
console.log(this.name); // 使用箭头函数,this 会继承 greet 方法中的 this
}, 1000);
}
};
person.greet(); // 输出 'Jane'
在上面的代码中,箭头函数不会重新绑定 this
,它会使用 greet
方法中的 this
,也就是指向 person
对象。
示例:
var people = {
name: 'elaine',
age: 28,
sayName: function(age) {
var sayAge = (age) => {
console.log(this)
this.age = age;
};
sayAge(age);
},
};
people.sayName(5);
上面代码中,sayAge中的this找到外层函数sayName中的this,实现功能。
四、this指向的改变
call
、apply
和 bind
改变 this
call
、apply
和 bind
是 JavaScript 中三个可以显式设置 this
的方法。它们允许你控制函数内部 this
的指向。
call
和apply
都是立即调用函数,并且允许你指定this
。bind
返回一个新的函数,允许你绑定this
,但是并不立即执行函数。
示例 1:call
和apply
const person = {
name: 'Alice'
};
function greet() {
console.log(`Hello, ${this.name}`);
}
greet.call(person); // 输出 'Hello, Alice'
greet.apply(person); // 输出 'Hello, Alice'
示例 2:bind
javascriptCopy Code
const person = {
name: 'Bob'
};
function greet() {
console.log(`Hello, ${this.name}`);
}
const greetBob = greet.bind(person);
greetBob(); // 输出 'Hello, Bob'
bind
创建了一个新函数,this
在该函数执行时会被绑定到 person
对象。
五、this优先级
1.显示绑定高于隐式绑定
案例:
var user = {
name: 'user',
foo: function(){
console.log(this.name)
}
}
var user1 = {
name: 'user1',
foo: function(){
console.log(this.name)
}
}
user.foo.call(user1)//user1
2.new高于隐式绑定
var user = {
name: 'lisa',
foo: function () {
console.log(this)
}
}
new user.foo() //foo{}
3.new高于显示绑定
function bar(){
console.log(this)
}
var fn = bar.bind('hello')
new fn() // bar
综上,以上四种绑定的优先级顺序为
new关键字 > 显式绑定 > 隐式绑定 > 默认绑定