JavaScript(14):this

  在JavaScript语言中,this是一个很神奇的存在,this指向是一个让初学者感到困惑和纠结的问题。

  有console.log函数帮助我们在学习过程中总结,this指向还是有一般规律可循的。

  1、在函数中直接使用时(不使用任何修饰符,比如call、apply、bind、new等),函数中的this默认绑定到全局,就是指向window。需要注意的是,当使用严格模式时,不能绑定到全局,程序会抛出错误。

	function func(){ console.log(this);	}
	func();

	a=function(){ console.log(this); }
	a();

	var b={ x:this }
	console.log(b.x);

   输出结果:

   2、在函数中的this指向不是在函数定义时确定的,需要在运行时确定,具体说就是this指向函数运行时的调用者。回调函数中的this一般指向调用者。

  这个好理解,在网页中我们经常使用回调函数,比如:

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
</head>
<body>
	<button id=demo>点击</button>
</body>
<script>
	demo.addEventListener('click',function(){
		console.log(self);//this指向window
		console.log(this);//this指向button
	})
	// document.getElementById("demo").addEventListener('click',function(){
	// console.log(self);//this指向window
	// console.log(this);//this指向button
	// })	
</script>
</html>

  下面的例子却有不一样的显示结果。

	function info(student){
		console.log(this);
		return '姓名:'+student.sName+',年龄:'+student.age+',性别:'+student.gender;
	}
	
	var student={
		sName:'无',
		age:0,
		gender:'无'
	}

	function sayHello(student,info){
		return info(student);
	}
	
	var stuA=new Object();
	stuA.prototype=student;
	stuA.sName='小王';
	stuA.age=11;
	stuA.gender='男';
	
	console.log(sayHello(stuA,info));
	
	var stuB=new Object();
	stuB.prototype=student;
	stuB.sName='小宋';
	stuB.age=9;
	stuB.gender='女';
	
	sayHello(stuB,function(stuB){
		console.log(this);
		console.log('姓名:'+stuB.sName+',年龄:'+stuB.age+',性别:'+stuB.gender);		
	});

  输出结果:

  回调函数里的this指向的是window。这个是可以理解的,因为回调函数info是由sayHello调用执行的,而sayHello中的this指向的就是window。

  在这个例子当中如果要使用this来改写,就可以使用call方法。

	function info(){
		console.log(this);
		return '姓名:'+this.sName+',年龄:'+this.age+',性别:'+this.gender;
	}
	
	var student={
		sName:'无',
		age:0,
		gender:'无'
	}

	function sayHello(student,info){
		return info.call(student);//绑定this到形参student所指的对象
	}
	
	var stuA=new Object();
	stuA.prototype=student;
	stuA.sName='小王';
	stuA.age=11;
	stuA.gender='男';
	
	console.log(sayHello(stuA,info));
	
	var stuB=new Object();
	stuB.prototype=student;
	stuB.sName='小宋';
	stuB.age=9;
	stuB.gender='女';
	
	sayHello(stuB,function(stuB){
		console.log(this);
		console.log('姓名:'+this.sName+',年龄:'+this.age+',性别:'+this.gender);		
	});

   使用call方法改变了回调函数中的this指向。

  3、函数中的方法调用,如果是绑定到属性,则是指向该属性的函数。

	function Info(Name,age,gender){
		console.log(this);
		return '姓名:'+Name+' 年龄:'+age+' 性别:'+gender;
	}
	console.log(Info('11','22','33'));
			
	var student={
		that:this,
		sName:'小红',
		age:11,
		gender:'女',
		sayHelloA:Info('100','200','300'),
		sayHelloB:Info,
		sayHelloC:Info,
		sayHelloD:function(){ return Info.call(this,this.sName,this.age,this.gender); },
		sayHelloE:function(){ return '★姓名:'+this.sName+' 年龄:'+this.age+' 性别:'+this.gender; }
	}
	
	console.log('---student中的this---');	
	console.log(student.that);	
		
	console.log('---student.sayHelloA---');
	console.log(student.sayHelloA);	

	console.log('---student.sayHelloB---');
	console.log(student.sayHelloB(student.sName,student.age,student.gender));	

	console.log('---student.sayHelloC---');
	console.log(student.sayHelloC.call(student,student.sName,student.age,student.gender));	
	
	console.log('---student.sayHelloD----');
	console.log(student.sayHelloD());
	
	console.log('---student.sayHelloE----');
	console.log(student.sayHelloE());

  输出结果:

   4、箭头函数,逐渐向外层父元素来查找this,箭头函数一般不重新绑定this指向。

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
</head>
<body>
	<button id=demo>点击</button>
</body>
<script>
	demo.addEventListener('click',function(){
		console.log(self);//this指向window
		console.log(this);//this指向button
		setTimeout.call(window,()=>{
			console.log('----------------');
			console.log(this);
		},1000);
	})
	// document.getElementById("demo").addEventListener('click',function(){
	// console.log(self);//this指向window
	// console.log(this);//this指向button
	// })	
</script>
</html>

  输出结果:  

   即使在settimeout函数中绑定了window,this指向输出的还是button。

  作为对比,如果换成普通函数,this的指向就改变了。

	demo.addEventListener('click',function(){
		console.log(self);//this指向window
		console.log(this);//this指向button
		setTimeout.call(window,function(){
			console.log('----------------');
			console.log(this);//指向window
		},1000);	
	})

  输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值