一、点击事件的this指向
点击事件中的this指向被点击的这个html元素。如下方代码,点击后this打印的是整个button元素。
<button id="box">按钮</button>
<script>
// 点击事件
box.onclick = function() {
// <button id="box">按钮</button>
console.log(this);
}
</script>
二、普通函数的this指向
普通函数的this指向调用者。如下方代码,调用fn1()的是window,所以this指向window。第二个对象中的普通函数,因为调用函数的是person对象,所以this指向person。
// 1.普通函数
function fn1() {
console.log(this);
}
// window
fn1()
//2.对象中的普通函数
let person = {
name:'wtx',
say() {
// person
console.log(this);
}
}
// person
person.say()
三、箭头函数的this指向
箭头函数没有自己的this,但可以从自己作用域链的上一层继承this。如果有嵌套,则继承父级的this;如果没有嵌套,箭头函数的this就会指向window。
(1)对象中含有一个普通函数,普通函数中嵌套一个箭头函数。
如下方代码,因为普通函数say()的调用者是person,所以普通函数的this指向person。又因为箭头函数在普通函数中嵌套着,所以箭头函数fn2()继承父级say()的this,也指向person。
//1.对象中含有普通函数,普通函数内部嵌套一个箭头函数
let person = {
name:'wtx',
say() {
// person
console.log(this);
let fn2 = () => {
// person
console.log(this);
}
fn2()
}
}
person.say()
(2)对象中含有一个箭头函数,箭头函数中又嵌套一个箭头函数。
如下方代码,因为箭头函数say()没有自己的this,所以不会指向调用者person,而是指向window。里层嵌套的箭头函数继承say()的this,也指向window。
let person2 = {
name:'wtx',
say: () => {
// window
console.log(this);
let fn2 = () => {
// window
console.log(this);
}
fn2()
}
}
person2.say()
四、构造函数的this指向
构造函数的this指向new实例化出来的对象。如下代码,Dog构造函数中的this指向第7行new出来的实例化对象Dog。
// this指向 new实例化出来的对象
function Dog() {
this.name = '大黄'
// Dog {name: '大黄'}
console.log(this);
}
let d1 = new Dog()
// Dog {name: '大黄'}
console.log(d1);
五、严格模式下的this
添加了"use strict",代码就进入了严格模式,这种情况下,全局普通函数的this就指向undefined。
"use strict";
function fn2() {
// 严格模式下,this指向undefined
console.log(this);
}
// undefined
fn2()
六、call、apply、bind改变this指向
如下代码,Xiaogou()的say()原本指向Dog中的'骨头',但18到23行通过call、apply、和bind改变了this的指向,让它指向了Cat,所以this就是Cat这个对象,this.eat指向的就是fish。
// call apply bind改变this的指向
let Cat = {
eat:'fish'
}
function Xiaodog() {
this.eat = '骨头'
}
Xiaodog.prototype.say = function() {
console.log(this.eat);
}
let dog = new Xiaodog()
// Xiaodog {eat: '骨头'}
console.log(dog);
// 骨头
dog.say()
// fish
dog.say.call(Cat)
// fish
dog.say.apply(Cat)
let binddog = dog.say.bind(Cat)
// fish
binddog()