# 浅谈this指向问题 🌱

this永远指向一个对象

# 普通函数调用

普通函数调用,this指向window 这里的this指向window是因为方法外层的this指向的是window

var name = '小白'
let age = 20
function fn () {
    console.log(this.name)  // 小白
    console.log(this.age)  // undefined
}
1
2
3
4
5
6

这里的this指向的就是windowvar声明一个变量就会在window下添加一个name属性,let声明不会在window创建。

# 箭头函数调用

箭头函数调用,箭头函数本身没有this,它的箭头函数继承外面环境的this

var name = '小白'
var obj = {
    age: 20,
    // 箭头函数的this指向
    arrow: () => {
        console.log(this.name)  // 小白
        console.log(this.age)  // undefined
    },
    // 普通函数的this指向
    general: function () {
        console.log(this.name)  // undefined
        console.log(this.age)  // 20
    }
}
obj.arrow()
obj.general()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 构造函数调用

构造函数调用,this指向实例对象

function person (name, age) {
    this.name = name
    this.age = age
    console.log(this)  // person{name: '小白', age: 30}
}
var p = new person('小白', 30)
1
2
3
4
5
6

# 对象方法调用

对象方法调用,this指向该方法所在的对象

var obj = {
    name: '小白',
    sex: '男',
    age: 20,
    general: function () {
        console.log(this)  // {name: "小白", sex: "男", age: 20, general: ƒ}
    }
}
obj.general()
1
2
3
4
5
6
7
8
9

# 事件绑定方法

事件绑定的方法,this指向该绑定事件的对象

<body>
    <button id="btn">点击一下</button>
</body>
<script>
    var btn = document.getElementById("btn")
    btn.onclick = function() {
        console.log(this)  // <button id="btn">点击一下</button>
    }
</script>
1
2
3
4
5
6
7
8
9

# 定时器函数

定时器函数,this指向window 这里的this指向window是因为方法外层的this指向的是window

var name = '小白'
setTimeout(function () {
    console.log(this)  // window
    console.log(this.name)  // 小白
}, 1000)
1
2
3
4
5

# 改变this指向

# call()方法

call(obj, firstName, ... , string),第一个参数objthis的指向对象,后面的参数就是传入方法的参数,参数数量不限,只需逗号隔开。

var obj = {
    name: '小白',
    age: 20,
    fn: function (x, y) {
        console.log(`${this.name}今年${this.age}岁,身高${x},体重${y}`)
        // 小红今年30岁,身高173cm,体重50kg
    }
}
var infor = {
    name: '小红',
    age: 30
}
obj.fn.call(infor, '173cm', '50kg')
1
2
3
4
5
6
7
8
9
10
11
12
13

# apply()方法

apply(obj, [firstName, ..., string]),第一个参数objthis的指向对象,后面将需要传入的参数整合成一个数组。

var obj = {
    name: '小白',
    age: 30,
    fn: function (x, y) {
        console.log(`${this.name}今年${this.age}岁,身高${x},体重${y}`)
        // 小红今年20岁,身高175cm,体重50kg
    }
}
var infor = {
    name: '小红',
    age: 20
}
obj.fn.apply(infor, ['175cm', '50kg'])
1
2
3
4
5
6
7
8
9
10
11
12
13

# bind()方法

bind(obj, firstName, ... , string),第一个参数objthis的指向对象,后面的参数就是传入方法的参数,参数数量不限,只需逗号隔开。

var obj = {
    name: '小白',
    age: 20,
    fn: function (x, y) {
        console.log(`${this.name}今年${this.age}岁,身高${x},体重${y}`)
    }
}
var infor = {
    name: '小青',
    age: 19
}
obj.fn.bind(infor, '175cm', '50kg')()  // 小青今年19岁,身高175cm,体重50kg
obj.fn.bind(infor, ['175cm', '50kg'])()  // 小青今年19岁,身高175cm,50kg,体重undefined
1
2
3
4
5
6
7
8
9
10
11
12
13