this
5大调用场景:
1.普通函数
2.对象方法
3.call、apply、bind
4.class
5.箭头函数
1.普通函数中的this
function fn(){
console.log(this);
}
fn(); //相当于下面的window.fn();
window.fn();
window调用了fn,所以this指向window
2.对象方法中出现this
let a={
name:'李四',
run:function(){
console.log(this.name)//this
}
}
a.run();// a 李四
a调用的run,所以run方法中的this指向pox
3.call() /apply() /bind() 都可以改变this指向
let obj={name:'小明'}
let pox={
name:'小红',
run:function(){
console.log(this.name)
}
}
// 对象方法中的this.指向方法的调用者。
pox.run();// pox 小红
pox.run.call(obj)// 小明
pox.run.apply(obj);// 小明
pox.run.bind(obj)();//小明
相同点:call() /apply() /bind() 都可以改变this指向,指向第一个参数
不同点:bind()需要手动执行
function foo(){
// argument=[参数] 类数组/伪数组
let arg=arguments;
let arr=[4,5,6]
// arg.push(4) 借用数组
// Array.prototype.push.call(arg,4) // arg==[1,2,3,4]
Array.prototype.push.apply(arg,arr) // arg==[1,2,3,4,5,6]
// Array.prototype.push.bind(arg)(4) // arg==[1,2,3,4]
console.log(arg);//[1,2,3]
}
foo(1,2,3)
不同点:call第二个参数为单个数值,apply()第二个参数为数组
4.class中的this指向new 后的实例对象
class Person{
constructor(name,age){
this.name=name;
this.age=age
}
say(){
console.log(`我叫${this.name}年龄是${this.age}`)
}
}
let lsy=new Person('李四',21);
lsy.say();// 我叫李四年龄是21
console.log(lsy);// {name:'李四',age:21}
class中的this指向new 后的实例对象
5.箭头函数中的this.指向父级上下文对象
let obj={name:'小明'}
var name='杨志' //不能用let声明,不存在变量提升
let pox={
name:'小红',
run:()=>{
console.log(this.name)//this
}
}
// 对象方法中的this.指向方法的调用者。
pox.run();// 杨志
pox.run.call(obj)// 杨志
pox.run.ally(obj);// 杨志
pox.run.bind(obj)();//杨志
class中的 this时刻指向父级的上下文对象。并且不可以被 call()/apply()/bind()修改。
6.特殊情况
对象方法中的this,指向当前对象(因为当前对象执行了方法)。
setTimeout函数中的this,相当于普通函数中的this,因为setTimeout触发的函数执行,并不是外部对象执行的。
setTimeout中函数是箭头函数,this为当前对象。因为箭头函数中的this始终是父级上下文中的this.
注意:
this取什么值,是在执行时确认的,定义时无法确认
手写bind:
// 模拟 bind
Function.prototype.bind1 = function () {
// 将参数拆解为数组
const args = Array.prototype.slice.call(arguments)
// 获取 this(数组第一项)
const t = args.shift()
// fn1.bind(...) 中的 fn1
const self = this
// 返回一个函数
return function () {
return self.apply(t, args)
}
}
function fn1(a, b, c) {
console.log('this', this)
console.log(a, b, c)
return 'this is fn1'
}
const fn2 = fn1.bind1({x: 100}, 10, 20, 30)
const res = fn2()
console.log(res)
this总结 (重要)
总之就这点内容
普通函数中调用,this指向window
对象方法中调用,this指向当前对象
call apply bind中调用, this指向被传入的对象
class中的方法中调用, this指向实例对象
箭头函数,this就是父级上下文中的this