技术社区通常用一句话总结了this
的指向问题:
谁调用它,
this
就指向谁。也就是说this的指向是在运行时刻指定的。
1.当一个函数独立运行的时候,函数的this应该指向Window对象、或者Global对象(在浏览器中Window就是该Global对象)、或者严格意义上应该是undefined。
function test(params) {
console.log(this) //Window
}
function test1(params) {
'use strict'
console.log(this) //undefined
}
test()
test1()
setTimeout(() => {
console.log(this) //Window
}, 1000);
2.一般使用new方法调用构造函数时,构造函数内的this指向会被绑定到新创建的对象上。
function Star(name,age){
this.name=name;
this.age=age;
this.sing=function(){
console.log(this.age);
}
}
var a=new Star("yang",12);
a.sing();// 12
3.在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。一般通过call/apply/bind方法显式调用函数时,函数体内的this会被绑定到指定参数的对象上。
var person1 = {
fullName: function() {
console.log(this.firstName + " " + this.lastName);
}
}
var person2 = {
firstName:"John",
lastName: "Doe",
}
// 使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法
person1.fullName.call(person2); // John Doe
person1.fullName.apply(person2); // John Doe
person1.fullName.bind(person2)(); // John Doe
function fun(a,b){
console.log(this,a,b);
}
fun.call({b:2},1,2);
fun.apply({b:2},[1,3]);
var saum=fun.bind({b:2},3,4);
saum();//bind 返回一个新方法 第一个参数 作为新方法的this指向
fun.call(121212,1,2);
fun.call('qqqqq',[1,3]);
通过以上代码可以看出:
call(),bind(),apply()这三个函数的第一个参数都是 this 的指向对象,第二个参数就有差别:
call()的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔。
apply()的所有参数都必须放在一个数组里面传进去。
bind()除了返回是函数以外,它的参数和 call 一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等。
4.对象方法中绑定,一般通过上下文对象调用函数时,函数体内的this会被绑定到该对象上。
var name = "aaa",age = 17
var obj = {
name:"bbb",
objAge:this.age, //this指Window
myFun:function(){
console.log(this) // this指obj,即obj调用的myFun
}
}
obj.myFun() //{name: 'bbb', objAge: 17, myFun: ƒ}
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
console.log(person.fullName()) //John Doe
5.箭头函数没有自己的this值,它的this值是继承它的父作用域的,箭头函数的this值是词法作用域,也就是说是在定义的时候就被指定了的,以后也不会随着它调用方法的改变而改变。
const obj = {
name:"xiaxia",
loves:["web","app","h5","java"],
printTec:function(){
console.log(this)
this.loves.map(item=>{
console.log(`${this.name} love ${item}`)
})
}
}
obj.printTec()