this
this关键字是JavaScript中最复杂的机制之一,它被自动定义在所有函数的作用域中。
———— 《你不知道的JavaScript 上》
一、this 是什么
-
随着代码的复杂程度提升,显式的传递上下文对象,会让代码越来越混乱,所以this 提供了一种更优雅的方式隐式的“传递”一个对象引用,因此api可以更加简洁并且易于复用
-
this的上下文取决于函数调用时的各种条件,
this的绑定和函数声明的位置没有任何关系
,只取决于函数的调用方式
二、判断this的方式
调用位置
找到函数被调用的位置,判断this的引用是什么
绑定规则
1. 默认绑定
let a = 2 ;
function foo(){
console.log(this.a);
}
foo() // 2 this指向了全局对象a
2. 隐式绑定
对象属性的引用只有最后一层调用生效。
const user = {
name:'小明'
seename:seename //注意此处声明,函数上下文发生了变化
}
function seename(){
consoel.log(this.name)
}
user.seename()// 小明
3. 显式绑定 (直接指定this的值)
在函数传参时使用 call()
或 apply()
方法 .
call()
的第一个参数会被传递给this
apply()
方法接受数组形式的参数,第一个参数会被传递给this。
let name='小明'
function seename(){
console.log(this.name)
}
seename.call('小张')// 小张
4. 硬绑定 function.prototype.bind()
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined 注意此时unboundGetX函数的调用位置是全局上下文
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // 42
5. new绑定
new在构造函数的时候做了什么?
- 创建(构造)一个新的对象
- 将对象绑定到构造函数的原型 (prototype)
- 这个对象会绑定到函数调用的this
- 如果没有返回其他对象,那么new 表达式中的函数调用会自动返回这个新对象