JavaScript this指向问题详解

几乎是JS独创的允许独立函数里出现this,使的大量的JS开发工作者,徒增大量的烦恼,但是这是js中必须要掌握的东西,所以不得不学习,为了避免忘记,现将此时此刻思路记录于此。核心思想:this始终指向的是调用它的对象。(本文章不讨论严格模式)

注意: const 和 let 声明的变量不是window对象,参考链接

1. 直接调用

毫无疑问this指向全局对象,例如window

var variable = 1;
console.log(window.variable);// 输出 1
console.log(this.variable);// 输出 1
console.log(this === window);// 输出 true
console.log(this);// 输出 Window

2. 普通函数方法调用

指向全局对象,例如window


function func(){
	var temp = 2;
	console.log(this);// 输出 Window
	console.log(temp);// 输出 2
	console.log(window.temp)// 输出 undefined PS:由于temp在函数内声明,属于局部变量,所以全局对象找不到temp
	console.log(this.temp);// 输出 undefined PS:由于temp在函数内声明,属于局部变量,所以全局对象找不到temp
}
func();
console.log(this.temp);// 输出 undefined PS:由于temp在函数内声明,属于局部变量,所以全局对象找不到temp

3. 对象函数调用

3.1 直接调用函数

这里的this指向的是对象obj,因为那个函数调用,this指向哪里,即this始终指向的是调用他的对象。

var a = 111;
var obj = {
	b:222,
	fc:function(){
		console.log(this);// 输出 {b: 222, fc: ƒ}
		console.log(this.b);// 输出 222
		console.log(this.a);// 输出 undefined
	}
}
obj.fc();

3.2 再赋值后调用

虽然obj2.fc是从obj1.fc赋值而来的,但是在obj2调用fc()时,obj2作为调用函数,this指向obj1。

var obj1 = {
	b:222,
	fc:function(){
		console.log(this.b);// 输出 222
	}
}
var obj2 = {
	b:333
}
obj2.fc = obj1.fc;
obj1.fc();// 输出 222
obj2.fc();// 输出 333

3.3 多层对象调用调用

尽管函数fc()被最外层对象outerObj调用,但是this指向的仍是它的上级对象innerObj。

var outerObj = {
	a:111,
	innerObj:{
		b:222,
		fc:function(){
			console.log(this.a);// 输出 undefined
			console.log(this.b);// 输出 222
		}
    }
}
outerObj.innerObj.fc();

4. 构造函数调用

指向构造函数内部,主要是因为是用new操作符调用构造函数的四个步骤:
(1) 创建一个新对象
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象
(3) 执行构造函数中的代码
(4) 返回新对象

var tempClass = function() {
	this.a = 111;
};
var tempClass = new tempClass();
console.log(tempClass.a);// 输出 111
tempClass.a = 222;
console.log(tempClass.a);// 输出 222

5. 箭头函数调用

箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定,即this是继承自父执行上下文。

var a = 111;
var obj = {
	a: 222,
	fc: () => {
		console.log(this.a);
	}
};
obj.fc();// 输出 111
var a = 111;
function tempClass() {
	this.a = 222;
	var fc = () => {
		console.log(this.a);
	};
	fc();
}
var tempClass = new tempClass();
// 输出 222

6. call、apply、bind方法作用

call()、apply()、bind() 都是用来重定义 this 这个对象的。

6.1 call

可以通过设置call方法的第一个参数改变this的指向对象。第一个参数之后的所有参数随便传。

var obj = {
	a: 111,
	fc: function(e1, e2) {
		console.log(this.a, e1, e2);
	}
};
var obj2 = obj.fc;
obj2.call(obj, 1, 2);// 输出 111 1 2

6.2 apply

可以通过设置apply方法的第一个参数改变this的指向对象。其余期望传入参数都必须放进一个数组,作为apply的第二个参数传入。

var obj = {
	a: 111,
	fc: function(e1, e2) {
		console.log(this.a, e1, e2);
	}
};
var obj2 = obj.fc;
obj2.apply(obj, [1,2]);// 输出 111 1 2

6.3 bind

bind会返回一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,而不是立即执行。

var obj = {
	a: 111,
	fc: function(e1, e2) {
		console.log(this.a, e1, e2);
	}
};
var obj2 = obj.fc;
obj2.bind(obj, 1, 2);
console.log(obj2);// 输出 ƒ (e1, e2) { console.log(this.a, e1, e2);}
obj2(3, 4);// 输出 111 3 4

7. return对this的影响

如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。参考链接

// 返回Number
function func1() {
	this.a = 111;
	return 1;
}
var temp1 = new func1;
console.log(temp1.a);// 输出 111

// 返回String
function func2() {
	this.a = 111;
	return '';
}
var temp2 = new func2;
console.log(temp2.a);// 输出 111

// 返回对象
function func3() {
	this.a = 111;
	return {};
}
var temp3 = new func3;
console.log(temp3.a);// 输出 undefined

// 返回Array
function func4() {
	this.a = 111;
	return [];
}
var temp4 = new func4;
console.log(temp4.a);// 输出 undefined

// 返回undefined
function func5() {
	this.a = 111;
	return undefined;
}
var temp5 = new func5;
console.log(temp5.a);// 输出 111

// 返回null。
function func6() {
	this.a = 111;
	return null;
}
var temp6= new func6;
console.log(temp6.a);// 输出 111

生活不易,你我共勉

引用其他人一个图片,感觉很到位
在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值