解决this指代的三种常用方法

解决this指代的三种常用方法

JavaScript语言的this对象一直是一个令人头痛的问题。在这里,我们以一个简单小例子来为大家讲解!

原文链接:https://editor.csdn.net/md/?articleId=105790363

直接上代码:

class Animal {
    constructor() {
        this.type = 'animal';
    }
    says(say) {   
    	setTimeout(function() {
        	console.log(this.type + ' says ' + say);
    	}, 1000);
    }   
} 
var animal = new Animal();
animal.says('hello'); 
//输出结果:undefined says hello
//注意:这里的this指向的是全局作用域,所以是undefined

分析原因:一般情况下setTimeout()的this指向window或global对象;而当使用类的方法时,需要this指向类实例,以下三种方法可以将this绑定到回调函数来管理实例

解决方法一(传统):赋值, 将this传给self,再用self来指代this
class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       var self = this;
       setTimeout(function() {
           console.log(self.type + ' says ' + say);
       }, 1000);
   }
} 
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello
解决方法二(ES5):bind(this)
class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       setTimeout(function() {
           console.log(this.type + ' says ' + say);
       }.bind(this), 1000);
   } 
} 
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello
解决方法三(ES6):箭头函数

注:箭头函数不改变this指代

class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       setTimeout(() => {
           console.log(this.type + ' says ' + say);
       }, 1000);
   }
} 
var animal = new Animal();
animal.says('hello');
//输出结果:animal says hello

下面咱们简单了解一下什么是bind()方法和箭头函数!

原文链接:https://editor.csdn.net/md/?articleId=105790363

bind()

bind()方法,顾名思义,就是绑定的意思

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,即从第二个参数起,会依次传递给原始函数

例如:fn.bind(obj),言外之意就是 obj.fn(),fn函数体内的this自然就指向obj

语法:fn.bind(this,arg1,arg2,…);

小例子:

var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		};
		fn();
	},
	c:'hello'
}
a.b();
// undefined world
//注:这里的this指代的是全局作用域,所以返回undefined
bind()绑定一
var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		}.bind(this);
		fn();
	},
	c:'hello'
}
a.b();
// hello world
//注:因为该函数是一个对象的方法,则它的this指针指向这个对象
bind()绑定二
var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		};
		fn.bind(this)();
	},
	c:'hello'
}
a.b();
// hello world
bind()传入多个参数
function fn(y,z){
	return this.x+y+z;
}
var obj = {
	x:2
};
var num = fn.bind(obj,3,5);
console.log(num()); //10
//注:bind方法会把它的第一个实参绑定给fn函数体内的this,所以这里的this即指向obj对象
//从第二个参数起,会依次传递给原始函数,即y=3,z=5

箭头函数

箭头函数是ES6新出来的写法,它的语法比函数表达式更简洁,并且没有自己的this、arguments、super或new.target

箭头函数不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字

箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数

箭头函数小细节:

1.如果参数只有一个,可以省略()
/*匿名函数*/
let fn1 = function(a){
	return a*a;
}
console.log(fn1(5));//25

/*箭头函数*/
let fn2 = n =>{
	return n*n;
}
console.log(fn2(5));//25
//注:虽然可以省略return,但为了方便阅读,建议保留return
2.如果return只有一条语句,可以省略{}
let fn = (a,b) => a + b;
console.log(fn(8,9));//17
3.不改变上下文的this指代
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="box1">按钮1</div>
		<div id="box2">按钮2</div>
		<script>
			let oBox1 = document.querySelector('#box1');
			let oBox2 = document.querySelector('#box2');
			
			console.log(this); //window
			
			//匿名函数
			oBox1.onclick = function(){
				console.log(this);
				//输出:<div id="box1">按钮1</div> 
				//this指代的是oBox1
			}
			
			//箭头函数:不改变上下文的this指代
			oBox2.onclick = () =>{
				console.log(this); //window
			}
		</script>
	</body>
</html>

注:箭头函数没有单独的this
如果是该函数是一个构造函数,this指针指向一个新的对象
在严格模式下的函数调用下,this指向undefined
如果是该函数是一个对象的方法,则它的this指针指向这个对象

原文链接:https://editor.csdn.net/md/?articleId=105790363

关于bind()和箭头函数就简单介绍到这里,想深入了解还需要查看官方文档!

学到很多东西的诀窍,就是一下子不要学很多 ——洛克

上一篇:python面向对象之多态鸭子类型与Java的比较


下一篇:drop out, learning rate in nn