javaScript中的 this
总结
- 什么是this?
- this的四种匹配规则
什么是 this ?
首先 this 是函数内部的一个特殊的对象, 存在于函数内部
清空对 this 的误解, 主要的误解有两点 , 这两点是不对的
- this 指向函数自身
- this 指向当前函数的作用域
正确的说法是, this 是都某个对象的引用, this 只有在运行的时候才真正的指定了对某个对象的引用, 而不是在你编写函数的时候确定的, this 的指向问题 之取决于函数调用的方式 可以大致分为四种方式
this 四种方式查询
1.默认规则
默认规则下的 this 在浏览器中指向 window
当函数没有任何的修饰直接调用, 匹配不到其他规则的时候 就会使用默认规则
var a = 1
function fn(){
abc()
}
function abc(){
console.log(this.a)
}
fn() // 1
2.隐式绑定
当某个函数 是某个对象的方法, 或者 某个对象的某个属性存储的是 某个函数的引用 这个时候 this 指向的是这个对象, 这个时候使用的就是隐式绑定了
let obj = {
a : 1,
fn : function() {
console.log(this.a)
}
}
obj.fn() // 1
function fn() {
console.log(this.a)
}
let obj = {
a: 1,
fn: fn
}
obj.fn() // 1
以上两种情况的 在 指向函数的时候 函数中的 this 都是使用的 隐式绑定 , console.log(this.a) 就是console.log(obj.a)
这是正常情况的隐式绑定规则, 但是隐式绑定中存在这一种隐式丢失情况, 这个时候使用的绑定规则默认规则
隐式丢失
先重新理解下隐式绑定, 当一个函数的引用被储存在对象的属性中(记住这个引用), 当我们调用的是这个 对象属性一开始对这个函数的引用的时候 才会发送隐式绑定, 如果是调用其他的对这个函数的引用, 这个时候就发生了丢失, this 使用 默认绑定
var a = 0
function fn() {
console.log(this.a)
}
var obj1 = {
a: 1,
fn: fn
}
var obj2 = {
a: 2,
fn: obj1.fn
}
var fn = obj2.fn
obj2.fn() // 2
fn() // 0
这里面, obj2的属性fn存储着对一个函数的引用, 如果你调用这个对象的fn 属性的这个对函数的引用, 那么这个时候使用的是隐式绑定, 但是 fn = obj2.fn 这一步 fn 得到的是一个新的对这个函数的引用 , 这个引用和对象中fn属性存储的对函数的引用, 虽然都是指向同一个函数, 但是你可以把它理解成一个新的引用,这个时候调用这个新的引用就不是按照隐式绑定, 因为隐式绑定的规则是 调用的对象某个属性中存储的对某个函数的引用, 这个时候使用默认绑定 指向window
3.硬绑定
使用 函数的 call, apply , bind 方法, 在函数调用的时候强制将函数的this 指向某个对象
function fn() {
console.log(this.a)
}
let obj = {
a: 1
}
fn.call(obj) // 1
4.通过new绑定
关键字 new 在使用的过程中, 做了下面四件事
- 创建一个对象
- 给这个指向原型操作
- 将函数的this指向这个对象
- 返回这个对象
function fn() {
this.a = 1 // 相当于 obj.a = 1
}
let obj = new fn()
console.log(obj.a) // 1
特殊的箭头函数
箭头函数是没有 this 的 他的 this 是继承来自外部的 this
并且 这个 this 不能被 call, bind , apply 修改
一道自测题
let obj1 = {
a: 1,
fn: function() {
return () => console.log(this.a)
}
}
let obj2 = {
a: 2
}
obj1.fn()() // 1
obj1.fn().call(obj2) // 1
obj1.fn.call(obj2)() // 2
分析
obj1.fn()() , obj1.fn() 得到了一个新的函数 但是这个函数是 箭头函数, 这里面 的this继承的是 obj.fn() 调用时 函数 里的this 指向 obj1
obj1.fn().call(obj2) obj1.fn() 返回一个箭头函数 , this 继承 指向的是 obj1 , 通过 call() 方法调用, 但是 call 箭头函数的this 是继承来的 不会被修改 所以还是指向 obj1
obj1.fn.call(obj2)() obj1.fn.call(obj2) 首先call() 方法调用了 fn 方法, 并且将这个fn 方法的this 指向了 obj2, 返回了一个箭头函数, 继承 fn this , 这个 this 指向的是 obj2

浙公网安备 33010602011771号