第一类:函数调用有.的调用情况,统一指向.前的对象
1, this->.前的对象
const obj={
name:'xhh',
fun:function(){
console.log(`姓名是:${this.name}`)
}
obj.fun() // 姓名是xhh
2,new 构造函数 this->new创建的新对象
const age = 12
function Obj (name, age) {
this.name = name
this.age = age
this.fun = function () {
console.log(this.age)
}
}
new Obj('xhh', 16).fun() // 16
3, 构造函数.prototype.fun=function(){}, 因为原型对象上的方法未来都是‘子对象.fun()’的方式调用, 所以this->将来调用fun()的.前的对象
function Obj (name, age) {
this.nage = name
this.age = age
}
Obj.prototype.fun = function (age) {
this.age += age
console.log(this.age)
}
const obj = new Obj('xhh', 12)
obj.fun(10) //22
第二类:函数调用既没有.也没用new的情况,在非严格模式下, this->window,严格模式下, this->undefiled
1,直接fun()调用
注意:此处和文档中第一类第一点的this指向对比进行区分
const name = 'zl'
const obj = {
name: 'xhh',
age: 16,
fun: function () {
console.log(`姓名是${name}`)
}
}
const fun = obj.fun
fun()//zl
2,匿名函数自调
(function (i) {
console.log(this)
})(1) //window
3,回调函数
setTimeout(function () {
console.log(this)
}, 0) //window
第三类,DOM事件处理函数,this->当前正在触发事件的.前的DOM对象
注意:此处的处理函数中的function不可以使用箭头函数,如果改为箭头函数, 则this指向了外层的window, 程序会报错
<div style="width: 500px;height: 500px;background-color: blueviolet;" id="button">点击</div>
const button = document.getElementById('button')
button.onclick = function () {
console.log(this) // id为'button'的DOM元素
}
第四类,箭头函数中的this,this->当前函数之外最近的作用域中的this
function fun () {
name = 'xhh'
age = 16
setTimeout(() => {
console.log(this.name)
}, 0)
}
fun() //xhh
其他:手动改变this指向,this绑定,apply,call,bind
- apply:临时指定this指向,并执行函数一次,第二个参数是数组类型,最后将会展开并一次赋值给arguments
- call:临时指定this指向,并执行函数一次,第二个参数以后依次会赋值给arguments
- bind:生成函数副本, 永久绑定this指向
- 箭头函数的底层原理就是bind绑定, 因此箭头函数无法再通过apply,call,bind改变this指向
const person = {
name: 'xhh',
age: 12
}
const person2 = {
name: 'zl',
age: 16
}
function fun () {
console.log(`姓名是:${this.name},年龄是:${this.age}`)
}
fun.call(person) //姓名是:xhh,年龄是:12
fun.call(person2)//姓名是:zl,年龄是:16
const fun1 = fun.bind(person)
fun1() //姓名是:xhh,年龄是:12