javascript中this的指向问题(包括普通函数和箭头函数)

一. 全局作用域或者普通函数中 this 指向全局对象 window。

①全局作用域

	console.log(this) //window

②普通函数(方法调用,是window对象调用的)

	function fun1 () {
		console.log(this)//window
	}
	fun1() //相当于window.fun1()

	//普通函数的嵌套
	var a=11
	function fun3(){
		console.log(this.a)//11 	因为是普通函数所以this指向window
		this.d=22;//因为this指向window,相当于在window对象添加一个d属性
		function fun31(){
			console.log(this.d);//22  因为是普通函数所以this指向window
		};
		fun31();
	}
	fun3();//相当于window.fun3()

	//和上面普通函数的嵌套进行区分,构造函数嵌套普通函数
	var y=11
	function Test(){
		console.log(this)//Test 实例
		this.y=22;
		let c=function(){
			console.log(this.y);//11 window
		};
		c();//window.c()
	}
	new Test();

③自执行函数this指向window

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

④定时器(setTimeout setInterval)环境this指向window

	setTimeout(function () {//相当于window.setTimeout()
		console.log(this);//window
	},1000);

⑤在普通对象里面this指向window

	var qq={
		a:this
	}
	console.log(qq)//{a:Window}
	console.log(qq.a)//Window

二. 在调用方法时谁调用的this就指向谁

①对象中方法的调用,this指向对象本身

	var obj1 = {
		fun4: function () {
			console.log(this)//obj1
		}
	}
	obj1.fun4()
		
	//事件绑定
	var btn = document.querySelector(".btn1")
	btn.onclick = function () {
		console.log(this) // btn1
	}
	
	//事件监听
	var btn = document.querySelector(".btn2")
		btn.addEventListener('click', function () {
			console.log(this) //btn2
	})

三.在构造函数或者原型对象中 this 指向构造函数的实例

这里需要说一下在使用构造函数创建实例时构造函数做了哪些工作(很重要):
1、创建一个空对象
2、使 this 指向这个空对象
3、执行构造函数为这个对象添加属性
4、返回此对象

①不使用new时(相当于普通函数)this指向window

	function Person1(name) {
		console.log(this); // window
		this.name = name;
	}
	Person1('jqy')

②使用new时 this指向构造函数的实例

	function Person2() {
		console.log(this) //people
		s = this//不声明 默认为全局变量
	}
	var people = new Person2()
	console.log(s === people) //true
	console.log(s === Person2) //false

③原型对象方法中的this指向实例对象

	function Person4() {}
	Person4.prototype.sayHi = function () {
	    console.log(this);//per4
	};
	var per4 = new Person4();
	per4.sayHi();

四.箭头函数中的this指向其外层作用域的this

箭头函数本身是没有 this 的。

//①
	var obj3 = {
	 	foo() {
	 		console.log(this);
		 },
		 bar: () => {
		  	console.log(this);
		 }
	}
	obj3.foo() // {foo: ƒ, bar: ƒ}
	obj3.bar() // window,指向外层 obj3 对象作用域
		
//②
	var obj4={
		fn:function(){
			console.log(this);//obj4
			var f=() => {   
		         console.log(this); //相当于上面2行 obj4
		         setTimeout(function() { //相当于window.setTimeout()
		         	console.log(this);//window
		         });
		    }
		    f();
		}
	}
	obj4.fn();

//③	区别与②
	var obj5={
		fn:()=>{
			console.log(this);//window
		    var f=() => {   
		    	console.log(this);//window
		        setTimeout(function() {
		        	console.log(this);//window
		         });
		    }
		    f();
		}
	}
	obj5.fn();
	//如果有多级箭头函数嵌套()=> () => () => this.a this指向第一个箭头函数的上一级对象。
		
//④箭头函数练习
	var a = 20;
	var obj6 = {
		a: 10,
		b: function() {
			console.log(this);
		    console.log(this.a);  
		},
		b1:this.a,
		c:{
		    a:50,
		    b:20,
		    fn:function(){        
		    	console.log(this.a);
		    }
		},
		d: () => {
			console.log(this.a);  
		},
		e: function() {
		 	return () => {
		   		console.log(this.a);
		    }
		}
	}
	obj6.b();//obj6 10  对象里面的方法谁调用指向谁  
	console.log(obj6.b1);//20  在对象{}里面,this指向window
	console.log(obj6.c.b);//20	对象中 this 指向window
	obj6.c.fn();//50   fn() 中的 this 指向对象c,区分下面的方法
	var f=obj6.c.fn;
	f();//20   指向window,window.f()
	obj6.d();//20  箭头函数没有自己的this,它只会从自己的作用域链的上一层继承this。 this 指向window 
	obj6.e()();//10  this指向obj6,相当于obj6调用obj6.e()返回的函数

			
//⑤例外:当构造函数中遇到retrun,如果返回值是一个对象,那么this指向的就是那个返回的对象
//否则this指向构造函数的实例。拿下面举例:
//在构造函数中使用 return 本身就有点扯,因为构造函数在 new 实例时本身会返回一个对象,如
//果又 return 一个对象的话就会覆盖构造函数本身返回的对象。所以下面问题的关键就是如果在
//构造函数return对象,那么这个对象会覆盖默认返回的对象,否则如果不自己主动return或者
//return非对象数据则返回默认对象。
	function Fn(){  
		this.user = '小明';  
		return {
			age:18,
			name:'qaz'
		};  
	}
	var a = new Fn();  
	console.log(a);//{age: 18, name: "qaz"}
	console.log(a.user); //undefined
		
	function Fn1(){  
		this.user = '小明';  
		return 1;
	}
	var a1 = new Fn1();  
	console.log(a);//fn {user: "小明"}
	console.log(a1.user); //小明
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值