this指向的优先级顺序为:new绑定 > 显式绑定 > 隐式绑定 > 默认绑定,箭头函数则采用词法作用域确定this。

JavaScript 函数的
this
this
new
call
apply
bind
this
要深入理解
this
默认绑定 (Default Binding) 这玩意儿最没存在感,但又无处不在。当一个函数作为普通函数被独立调用,没有任何其他绑定规则施加影响时,
this
window
global
this
undefined
undefined
function showThis() {
console.log(this);
}
showThis(); // 浏览器非严格模式下:Window 对象;Node.js 非严格模式下:Global 对象
// 'use strict';
// showThis(); // 严格模式下:undefined隐式绑定 (Implicit Binding) 这是最常见的,也是最容易让人误解的。当函数被作为某个对象的方法调用时,
this
const person = {
name: 'Alice',
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // Hello, my name is Alice (this 指向 person)但这里有个经典的“
this
person.greet
const sayHello = person.greet; sayHello(); // Hello, my name is undefined (非严格模式下,this 指向 Window/Global,name 属性不存在)
显式绑定 (Explicit Binding) 当你想强行指定
this
call()
apply()
bind()
this
call(thisArg, arg1, arg2, ...)
apply(thisArg, [argsArray])
bind(thisArg, arg1, arg2, ...)
this
thisArg
function introduce(age, city) {
console.log(`My name is ${this.name}, I am ${age} years old and live in ${city}.`);
}
const anotherPerson = { name: 'Bob' };
introduce.call(anotherPerson, 30, 'New York'); // My name is Bob, I am 30 years old and live in New York.
introduce.apply(anotherPerson, [25, 'London']); // My name is Bob, I am 25 years old and live in London.
const boundIntroduce = introduce.bind(anotherPerson, 40);
boundIntroduce('Paris'); // My name is Bob, I am 40 years old and live in Paris.一个需要注意的“陷阱”是,如果你给
call
apply
bind
null
undefined
thisArg
this
new
this
new
this
new
function Car(make, model) {
this.make = make;
this.model = model;
// console.log(this); // 这里的 this 就是新创建的 Car 实例
}
const myCar = new Car('Honda', 'Civic');
console.log(myCar.make); // Honda在这种情况下,
this
词法绑定 (Lexical Binding) - 箭头函数 箭头函数,这家伙就是个“叛逆者”,它根本不关心自己的
this
this
this
this
this
const user = {
name: 'Charlie',
logName: function() {
setTimeout(function() {
console.log(this.name); // 默认绑定,this 指向 Window/Global,输出 undefined
}, 100);
},
logNameArrow: function() {
setTimeout(() => {
console.log(this.name); // 词法绑定,this 继承自 logNameArrow 所在的 user 对象,输出 Charlie
}, 100);
}
};
user.logName();
user.logNameArrow();因此,箭头函数实际上是跳过了前面四种规则,直接从外层作用域“借用”
this
this
理解
this
new
new
this
call()
apply()
bind()
this
bind()
this
new
this
this
undefined
箭头函数的特殊性: 箭头函数是个“局外人”,它不参与这个优先级排序。它的
this
call
apply
bind
new
new
this
this
this
this
this
回调函数中的 this
setTimeout
map
filter
const counter = {
count: 0,
increment: function() {
console.log(this.count++); // 期望是 this 指向 counter
},
start: function() {
setTimeout(this.increment, 1000); // 陷阱!this.increment 被作为普通函数调用
}
};
counter.start(); // 1秒后输出 NaN 或报错,因为 this 变成了 Window/Global这里的
this.increment
setTimeout
this
counter
window
undefined
事件处理函数中的 this
this
<button id="myButton">Click Me</button>
<script>
const app = {
name: 'My App',
handleClick: function() {
console.log(`App name: ${this.name}`); // 期望 this 指向 app
console.log(`Button ID: ${this.id}`); // 期望 this 指向 button
}
};
document.getElementById('myButton').addEventListener('click', app.handleClick);
// 点击按钮后:App name: undefined (this 指向 button,button 没有 name 属性)
// Button ID: myButton
</script>这里
app.handleClick
this
myButton
this.name
app
name
call
apply
bind
null
undefined
this
null
undefined
function greet() {
console.log(`Hello, ${this.name || 'Stranger'}`);
}
const globalName = 'World'; // 在全局作用域定义
greet.call(null); // Hello, World (非严格模式下,this 指向 Window/Global)
// 'use strict';
// greet.call(null); // Hello, Stranger (严格模式下,this 仍为 null/undefined,没有 name 属性)这可能导致意外地访问到全局变量,或者在严格模式下直接报错,而不是你期望的
this
null
undefined
箭头函数与传统函数的混用 箭头函数因为其词法
this
const myObject = {
value: 10,
getValue: function() {
return this.value; // this 指向 myObject
},
getArrowValue: () => {
return this.value; // 陷阱!this 指向定义时的全局对象(Window/Global),而不是 myObject
}
};
console.log(myObject.getValue()); // 10
console.log(myObject.getArrowValue()); // undefined (或全局对象的 value 属性)getArrowValue
this
myObject
myObject
this
有效地管理
this
使用 bind()
this
bind()
this
const counter = {
count: 0,
increment: function() {
console.log(++this.count);
},
start: function() {
// 使用 bind 绑定 this 到 counter 对象
setTimeout(this.increment.bind(this), 1000);
}
};
counter.start(); // 1秒后输出 1对于事件监听器,这也是一个常见且有效的模式。
利用箭头函数的词法 this
this
this
this
this
const user = {
name: 'David',
greetDelayed: function() {
// 这里的 this 指向 user
setTimeout(() => {
// 箭头函数捕获了外层 greetDelayed 的 this,所以也指向 user
console.log(`Hello, ${this.name}`);
}, 500);
}
};
user.greetDelayed(); // 0.5秒后输出 "Hello, David"当你在一个方法内部需要定义另一个函数,并且希望这个内部函数的
this
使用 call()
apply()
this
this
call()
apply()
this
function displayInfo(message) {
console.log(`${message}: ${this.id}`);
}
const element = { id: 'my-element' };
displayInfo.call(element, 'Element ID'); // Element ID: my-element这在需要借用其他对象的函数时特别有用,例如,将一个数组方法应用于一个类数组对象。
在构造函数中使用 new
class
new
this
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
const p = new Person('Eve');
p.sayName(); // Eve在这种模式下,你通常不需要手动干预
this
new
总的来说,管理
this
this
this
this
以上就是JS 函数绑定与 this 指向 - 五种绑定规则的优先级与例外情况的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号