javascript的this指向问题

关于this指向问题一直是js基础的热门问题,最近参与公司面试问过很多面试者总觉得有点模糊。所以自己想着总结一下:

this的指向在函数定义的时候是确定不了的,只有在函数执行的时候,指向调用它的对象。

一、全局环境

在全局环境中,this都是指向全局对象window。

console.log(this); //window
二、函数环境
1、普通函数

普通函数调用是window的调用,this 指向window。

function fn(){
	console.log(this);//window ,严格模式返回undefined
}
fn(); // window.fn(),window可以省略

示例:

let a = 'aa';
fuunction fn(){
	console.log(this.a); //undefined
}
fn();
var a = 'aa';
fuunction fn(){
	console.log(this.a); //'aa'
}
fn();

let定义的是局部变量,var定义的是全局变量。

2、构造函数

当函数作为构造函数时,它的 this 会被绑定到实例上。

function fn(){
	console.log(this); // this指向func
}
let func = new fn();

示例:

function fn(){
	this.a = 'aa';
}
let func = new fn()
console.log(func.a); //'aa'
3、对象调用

那个对象调用 this 就指向那个对象。

let obj = {
	fn:function(){
		console.log(this); //obj
	}
}
obj.fn();

示例:

let obj = {
	a:'aa',
	fn:function(){
		return this.a;
	}
}
console.log(obj.fn);//'aa'
4、箭头函数

箭头函数里面,没有 this;this 继承外面的环境。

let fn = (()=>{console.log(this)});//window

示例:

let obj={
	a:222,
	fn:function(){ 
		setTimeout(()=>{console.log(this.a)});
	}
};
obj.fn();//222

箭头函数的外部环境是fn,fn是obj调用的,this指向obj

5、定时器 / 计时器

this 指向window

setInterval(function(){
	console.log(this); //window
},1000)

示例:

var a = 111
let obj={
	a:222,
	fn:function(){ 
		setTimeout(function(){console.log(this.a)});
	}
};
obj.fn();//111
6、匿名函数

this指向 window

(function(){
	console.log(this);//window 
})()
三、DOM事件和内联事件

1、DOM事件
当函数被当做监听事件处理函数时, 其 this 指向触发该事件的元素 (针对于addEventListener事件)

function fn(){
	console.log(this); //指向btn
}
let btn = document.getElementById('btn');
btn.addEventListener('click',fn,false);

2、内联事件
内联事件中的this指向分两种情况:
①、当代码被内联处理函数调用时,它的this指向监听器所在的DOM元素
②、当代码被包括在函数内部执行时,其this指向等同于 函数直接调用的情况,即在非严格模式指向全局对象window, 在严格模式指向undefined

<button onclick="console.log(this)"></button> //当前DOM
<button onclick="(function(){console.log(this)})"></button> // window
四、改变this指向(call / apply)

call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。
1、call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。
2、apply接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)

let fn = function(a,b,c){
	console.log(a,b,c)
}
let arr =[1,2,3]
fn.call(window,arr) => [1,2,3] undefined undefined
fn.apply(window,arr) => 1,2,3

let obj1={
	a:222
};
let obj2={
	a:111,
	fn:function(){
		alert(this.a);
	}
}
obj2.fn.call(obj1) =>222

虽然调用的是obj2,但是call把this指向了obj1,所以obj2.fn的执行环境是obj1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值