Js中的this指向问题
this的指向在函数刚定义的时候是没发确定的,只有在函数执行的时候才能确定this到底指向谁。也就是说this最终指向的是调用它的那个对象
Example 1:
function fn1(){
let name = 'mike'
console.log(name) //mike
console.log(this.name) //undefined
console.log(this) //window
}
fn1()
如果一个函数的调用方式为fn1()
,它是相当于window.fn1()
。所以函数fn1
中的this
指向的是window
,那么window
下没有name
这个变量所以当打印this.name
的时候自然等于的是undefined
Example 2:
let fn1 = {
name:'mike',
fn2:function(){
console.log(this)// 指向函数fn1
console.log(this.name)// mike
}
}
fn1.fn2()
函数fn2
是通过函数fn1
调用执行的,所以当前的this
指向的是函数fn1
Example 3:
let fn1 = {
name:'mike',
fn2:function(){
console.log(this)// 指向函数fn1
console.log(this.name)// mike
}
}
window.fn1.fn2()
到这里你可能会问了这里的this
为什么指向的不是window
,this
最终指向的不是调用它的对象吗
window
对象是js中的一个全局对象,实际我们声明变量都是再给window
添加属性
再看Example 4:
let fn1 = {
name:'mike',
obj:{
name:'russ',
fn2:function(){
console.log(this)// 指向obj
console.log(this.name)// russ
}
}
}
fn1.obj.fn2()
这里也是fn1
执行调用的,但是this
同样没有指向它
this
指向的问题可分为三种情况:
- 如果一个函数中存在着
this
,但是没有被任何对象进行调用,那么它一定指向的是window
- 如果一个函数中存在着
this
,但被它的上一级调用了,那么它指一定向的是上一级的作用域 - 如果一个函数中存在着
this
,但是这个函数包含着多个对象,尽管这个函数是被最外层的对象所调用,它也一定指向的是它的上一级的作用域(如例4)
但还存在着一种特殊的情况 Example 5:
let fn1 = {
name:'mike',
obj:{
name:'russ',
fn2:function(){
console.log(this)// window
console.log(this.name)// undefined
}
}
}
let fn3 = fn1.obj.fn2()
fn3()
懵了!这里为什么又是指向的window
.根据例4我们可以得出this
指向的永远是最后调用他的那个对象,例5中虽然函数fn2
是被对象obj
所引用,但是在将fn2
赋值给变量fn3
的时候并没有执行所以最终指向的是window
构造函数的this指向:
function fn1 () {
this.name = 'mike'
}
let fn2 = new fn1()
console.log(fn2.name)// mike
这里fn2
能直接访问fn1
里面的name
属性是因为构造函数的关键字new
可以改变this
的指向。为什么说fn2
是一个对象而例5却不是,主要原因还是在于new
关键字创建的是一个实例对象,调用函数fn1
的是fn2
对象,既然是对象,那么this
自然指向的是fn2
。为什么fn2
中会有name
属性,因为用了new
相当于等同的复制了fn1
函数。