首先我们来看一看this的定义:this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象。
函数里面的this,一定是函数调用的时候自动产生的,就是一个变量
分析函数内的this首先要分析函数定义声明的位置。
要注意:无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。
在绝大多数情况下,函数的调用方式决定了this对象的指向(谁调用函数,函数内部的this值就指向谁.)
根据不同的使用场合,this 对象有不同的指向,主要分为下面几种情况:
(1)默认绑定:
全局环境中定义的函数,函数内部的 this 指向 window 对象
(2)隐式绑定:
<script>
function a() {
console.log(this.x)
}
let obj = {
x: 1,
y: a
}
obj.y()
</script>
函数还可以作为某个对象的方法调用,这时 this 就指这个上级对象. obj.y()调用过后,控制台应该打印1。
(3)new绑定:
通过构建函数 new 关键字生成一个实例对象,此时 this 指向这个实例对象
(4)显示绑定:
apply()、call()、bind()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时 this 指的就是这第一个参数
(5)箭头函数:
箭头函数不提供自身的this绑定。箭头函数: 内部没有绑定的this值,对于箭头函数来说, 里面的this值,就是当前箭头函数定义的位置的上一层作用域的this值。它的取值遵循普通普通变量一样的规则,在函数作用域链中一层一层往上找。
下边是一些简单的js小题目看一看里边的this指向的是谁?
<button class="btn">测试</button>
<script>
document.querySelector('.btn').addEventListener('click', function () {
// 函数里面的this,一定是 函数调用的时候 自动产生的, 就是一个变量
console.log(1, this); //获取的button按钮 dom对象
setTimeout(function () {
console.log(2, this); // window
}, 1000);
// 分析函数定义的位置, 和函数调用的位置
setTimeout(() => {
console.log(3, this); //获取的button按钮
}, 1000);
});
</script>
如上方代码显示:3次控制台打印分别为:获取的button按钮 dom对象,全局对象window,获取的button按钮 dom对象。
第一个this调用其函数的是button按钮这个dom对象,谁调用函数,this指向谁。所以第一个打印出来的是button俺就这个dom对象。
第二个this它虽然是写在setTimeout第一个参数函数里的,但是实质上调用它的还是全局对象,所以它的this指向是window全局对象.
第三个this.它是写在setTimeout第一个参数函数里的,但是这个函数为箭头函数,没有绑定的this,它的上次作用域在点击事件的函数内,所以它的this指向button按钮这个dom对象
document.querySelector('.btn').addEventListener('click', () => {
console.log(this);
})
上方代码,点击事件的函数为一个箭头函数,上一层作用域为全局对象,所以打印的应该是window全局变量。但不建议这样写,this指向don对象方便代码编写,可以少声明一个变量。
<script>
var myName = 1;
var obj = {
myName: 2,
func: function (a) {
const b = 12;
console.log('1:', this === obj);
return {
myName: 3,
getName1: () => {
console.log('2:', this);
console.log('3', this.myName);
},
getName2: function () {
console.log('4:', this);
console.log('5', this.myName);
},
};
},
};
// 谁调用函数, 函数内部的this值就指向谁
const a = obj.func(1);
a.getName1()
a.getName2()
</script>
控制台打印的this其中'1'和'2'打印的都是对象obj,'4'是return返回的这个对象。 '3'的myName为2.'5'的myName为3。
<script>
const o1 = {
address: '北京',
getList() {
// 定义一个变量接受外层函数的this值,然后后面所有的函数,this都是用定义的变量self来进行操作
const self = this;
console.log(1, this); // o1
// 普通函数 就要看 在函数调用的位置确定this值
const fn = function () {
console.log(2, this); // window
console.log(222, self);
};
// 一个函数里面的函数,如果自己直接调用,那么this就是window
fn(); // 像这种函数就是 window.fn()
// 箭头函数,就是要看,函数定义的位置确定this值
const fn2 = () => {
console.log(3, this); // o1
};
fn2();
},
};
o1.getList()
</script>
<script>
var o = {
a: 10,
b: {
a: 12,
fn: function () {
console.log(this);
},
},
};
// 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级(不是箭头函数,是对象.符号的前一个)的对象
// 谁调用这个函数,函数里面的this值就等于谁
o.b.fn();
const o2 = o.b.fn;
o2(); // window.o2()
</script>