Skip to content

this 指向

this 的指向不是在函数定义时确定,而是在函数执行时确定(箭头函数除外),本质是指向调用函数的对象

全局作用域/普通函数

执行环境this 指向严格模式差异
浏览器window 对象普通函数内 this → undefined
Node.jsglobalThis(函数内)
module.exports(全局)
函数内 this → undefined

代码开头加 'use strict' 后 JS 进入严格模式

js
// 浏览器非严格模式
console.log(this === window); // true
function fn() {
    console.log(this);
}
fn(); // window

// 严格模式
'use strict';
function fn2() {
    console.log(this);
}
fn2(); // undefined

// Node.js 环境
function fn3() {
    console.log(this);
}
fn3(); // globalThis
console.log(this); // module.exports(空对象)

对象方法调用

this 指向直接调用方法的对象(方法名前的对象)。方法赋值给变量后,失去原对象绑定,变成全局调用

js
const obj = {
    name: '张三',
    sayHi() { console.log(this.name); },
    child: {
        name: '李四',
        sayHi() { console.log(this.name); }
    }
};
obj.sayHi(); // 张三(this → obj)
obj.child.sayHi(); // 李四(this → obj.child)

const fn = obj.sayHi;
fn(); // undefined(this → window/globalThis)

构造函数(new 调用)

this 指向new 创建的实例对象

js
function fun(name) {
    this.name = name;
}

f1 = new fun('张三');
console.log(f1.name); // 张三

特殊

场景this 指向
DOM 事件处理函数触发事件的DOM
时器 / 延时器默认全局(严格模式 undefined)

修改指向

js
const user1 = { name: "张三", sayHi(msg = "") { console.log(`你好,${this.name}。${msg}`); } };
const user2 = { name: "李四" };

// 直接调用,this 指向 user1
user1.sayHi(); // 你好,张三。

// 抽离方法后调用,this 丢失,指向全局
const sayHi = user1.sayHi;
sayHi(); // 你好,undefined。(全局无name属性)

上述代码中方法内部已经存在 this 的使用,但是因为方法被抽离后导致 this 丢失。而 JS 提供了 callapplybind 三个原生方法,主动改变函数执行时 this 的指向,不在遵循谁调用,this 指向谁的默认规则

方法执行时机参数传递核心作用
call立即执行逐个传参临时修改 this 并执行
apply立即执行数组传参适合参数数量不确定时
bind返回新函数逐个传参(可预填)永久绑定 this,按需执行

语法:函数.方法(新的this指向, 参数)

call

格式:函数.call(新的this指向, 参数1, 参数2, 参数n)

调用后会立即执行该函数,参数逐个传入。适合固定参数

js
sayHi.call(user2); // 你好,李四。
sayHi.call(user2, "今天天气真不错"); // 你好,李四。今天天气真不错

apply

格式:函数.apply(新的this指向, 参数数组)

调用后会立即执行该函数,参数通过数组动态传递。适合参数数量不确定

js
sayHi.apply(user2); // 你好,李四。
let arr = []
arr.push("今天天气真不错");
sayHi.apply(user2, arr); // 你好,李四。今天天气真不错

bind

格式:[const/var/let] 变量名 = 函数.bind(新的this指向, 参数1, 参数2, 参数n)

不立即执行函数,返回一个绑定了新 this的新函数;可预填参数(柯里化)

js
let fun1 = sayHi.bind(user2, "今天天气真不错");
fun1(); // 你好,李四。今天天气真不错
fun1("确实不错"); // 你好,李四。今天天气真不错

let fun2 = sayHi.bind(user2);
fun2("今天天气真不错"); // 你好,李四。今天天气真不错
fun2("确实不错"); // 你好,李四。确实不错