Javascript 编程基础(4)函数 | 4.2、this 绑定机制
文章目录
- 一、this 绑定机制
- 1、原理分析
- 1.1、动态绑定特性
- 1.2、绑定规则优先级
- 1.3、执行上下文
- 2、绑定类型详解
- 2.1、默认绑定(独立函数调用)
- 2.2、 隐式绑定(方法调用)
- 2.3、显式绑定(call/apply/bind)
- 2.4、new 绑定(构造函数)
- 2.5、箭头函数(词法绑定)
一、this 绑定机制
1、原理分析
this
是 JavaScript 中最容易混淆的概念之一,它的绑定机制决定了函数执行时的上下文。理解this
的工作原理对于编写可靠的 JavaScript 代码至关重要。
1.1、动态绑定特性
this
的值不是在函数定义时确定的,而是在函数被调用时动态绑定的。这与大多数编程语言中的this
或self
概念有显著区别。
1.2、绑定规则优先级
JavaScript 按照以下优先级顺序确定
this
的绑定:
new
绑定(构造函数调用)- 显式绑定(call/apply/bind)
- 隐式绑定(方法调用)
- 默认绑定(普通函数调用)
1.3、执行上下文
this
实际上是执行上下文的一个属性,每次函数调用都会创建一个新的执行上下文,其中的this
值由调用方式决定。
2、绑定类型详解
2.1、默认绑定(独立函数调用)
- 非严格模式下指向全局对象(浏览器中为
window
,Node.js 中为global
) - 严格模式下为
undefined
function foo() {console.log(this);
}foo(); // 浏览器中输出 window(非严格模式)
2.2、 隐式绑定(方法调用)
- 函数作为对象方法调用时,
this
指向调用该方法的对象 - 存在隐式丢失问题
const obj = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}`);}
};obj.greet(); // "Hello, Alice"(this 指向 obj)// 隐式丢失示例
const greetFn = obj.greet;
greetFn(); // "Hello, undefined"(this 指向全局)
2.3、显式绑定(call/apply/bind)
- 直接指定
this
的值 bind
创建永久绑定,call/apply
立即执行
function introduce(lang) {console.log(`${this.name} codes in ${lang}`);
}const dev = { name: 'Bob' };// call(参数逐个传递)
introduce.call(dev, 'JavaScript'); // apply(参数为数组)
introduce.apply(dev, ['Python']); // bind(创建新函数)
const boundFn = introduce.bind(dev, 'Java');
boundFn();
2.4、new 绑定(构造函数)
this
指向新创建的对象实例- 自动执行以下步骤:
- 创建新对象
- 将
this
绑定到新对象 - 执行构造函数代码
- 返回新对象(除非显式返回其他对象)
function Person(name) {this.name = name;
}const p = new Person('Charlie');
console.log(p.name); // "Charlie"
2.5、箭头函数(词法绑定)
- 继承定义时的外层
this
值 - 无法通过 call/apply/bind 修改
- 没有自己的
this
、arguments
、super
或new.target
const outer = {name: 'Dave',inner: () => {console.log(this.name); // 继承定义时的 this},properInner: function() {setTimeout(() => {console.log(this.name); // 继承 properInner 的 this}, 100);}
};