什么是this指向?
不管在什么地方使用this,它最终指向一个对象;而this的使用地方在哪里,到底会指向哪个对象就取决于函数调用的位置了。总之,记住一句话:
哪个对象调用函数,函数里面的this指向哪个对象。
不同场景中的this指向
一、普通函数调用
此时,this指向window对象
function fn() {
console.log(this);
}
fn(); // 全写是window.fn(),此处省略了window. 输出结果是 window 对象
打印结果:
二、对象函数调用
此时,this 指向该方法所属的对象
let a = {
name: "aaa",
fn: function () {
console.log(this);
}
}
a.fn(); //输出结果是 a 对象
打印结果:
function fn() {
console.log(this);
}
let a = { name: "aaa", fn: fn } //a对象的fn方法指向全局函数fn
a.fn(); // 调用者是a对象,输出结果仍然是 a 对象
打印结果:
三、构造函数调用
此时,this指向新创建出来的实例化对象
function fn() {
this.name = "名字"; // 这个值取决于new出来的实例
}
let a = new fn(); // 创建一个实例
a.name = "aaa"; // 实例重置了name属性的值
console.log(a.name);
打印结果:
四、箭头函数调用
指向箭头函数定义时所处的对象,而不是箭头函数使用时所在的对象,默认使用父级的this。
let obj = {
name: "aaa",
fn: () => {
console.log(this);
}
}
obj.fn();
此时,函数fn的父级this指向window
打印结果:
function f() {
let obj = {
name: "aaa",
fn: () => {
console.log(this.name);
}
}
obj.fn();
}
let b = {
name: "bbb",
f: f // 此处的f 方法指向全局函数 f
}
b.f()
打印结果:
箭头函数中的this,首先从它的父级作用域中找,如果父级作用域还是箭头函数,再向上找,如此直至找到this的指向
五、事件绑定调用
- 在元素上直接绑定
<body>
<input type="button" id="btn" value="点我试试" onclick="fn()"></input>
</body>
<script>
function fn() {
console.log(this);
}
</script>
此时 this 指向 全局变量 window
打印结果:
2. js获取元素再绑定
<body>
<input type="button" id="btn" value="点我试试"></input>
</body>
<script>
document.getElementById('btn').onclick = function () {
console.log(this);
}
</script>
此时的 this 指向 该元素
打印结果:
如何改变this指向?
函数作为对象提供了call(),apply() 方法,他们也可以用来调用函数,这两个方法都接受一个对象作为参数之一,用来指定本次调用时函数中this的指向。
apply和call调用
- call()方法:
接收的参数个数不固定
函数名称.call(obj,arg1,arg2…argN);
参数说明:
obj:函数内this要指向的对象,
arg1,arg2…argN :参数列表,参数与参数之间使用一个逗号隔开
var Lily = { name: 'Lily' };
var Marry = {
name: 'Marry',
baseInfo: function f(age, sex) {
console.log("姓名:", this.name);
console.log("年龄:", age);
console.log("性别: ", sex);
}
};
Marry.baseInfo.call(Lily, 18, "女"); // call改变了this的指向,此时baseInfo方法中的this指向Lily对象
打印结果:
2. apply()方法:
接收两个参数
函数名称.apply(obj,[arg1,arg2…,argN])
参数说明:
obj :this要指向的对象
[arg1,arg2…argN] : 参数列表,要求格式为数组
var Lily = { name: 'Lily' };
var Marry = {
name: 'Marry',
baseInfo: function f(age, sex) {
console.log("姓名:", this.name);
console.log("年龄:", age);
console.log("性别: ", sex);
}
};
Marry.baseInfo.apply(Lily, [18, "女"]); // apply改变了this的指向,此时baseInfo方法中的this指向Lily对象
打印结果:
注意:call() 和 apply()的作用相同,唯一的区别就是传参方式不同