箭头函数与普通函数的区别

349 阅读3分钟

箭头函数与普通函数有什么区别?

1.箭头函数与function定义函数的写法:
	普通函数:function fn(a,b){};
	箭头函数:var fn = (a,b)=>{};

2.this指向:
	使用function定义的函数,this的指向是随着调用环境的变化而变化的,而箭头函数中的this指向是固定不变的,一直指向的是定义函数的环境
	
	普通函数:
		function fn(){ console.log(this) }
		var obj = {aa: fn};
		fn();			// window
		obj.aa();		// obj
	箭头函数:
		var fn = ()=>{ console.log(this) };
		var obj = {aa: fn};
		fn();		// window
		obj.aa();	// window
		
3.构造函数
	普通函数:
		每个新定义(function)的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被称为“对象方法”则为基础对象等)
		function Fn(){ this.a = 1; }
		var obj = new Fn();
		obj.a = 1;
	箭头函数:(箭头函数表达式的语法比函数表达式更短,并且不绑定自己的this,arguments,super或 new.target。这些函数表达式最适合用于非方法函数,并且它们不能用作构造函数。)
		// 注:严格模式下,箭头函数中的this指向window
		// 箭头函数不会创建自己的this;它使用封闭执行环境上下文的this值。
		// 箭头函数中的this是无法被修改的(call,apply,bind)
		// 箭头函数中也没有arguments.
		// 箭头函数没有prototype属性。
		var Fn = ()=> { this.a = 1; }
		var obj = new Fn();		// Fn is not a constructor

4.变量提升
	由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
	普通函数:
		fn();
		function fn(){}

	箭头函数:
		Fn();	// Fn is not a function
		var Fn =()=>{};

面试题一道

var x = 2;
var y = {
	x: 3,
	z:(function(x){
		this.x *= x;
		x+=2;
		return function(n){
			this.x *= n;
			x += 3;
			console.log(x);
		}
	})(x)
	    
	// 自执行函数先执行,所以自执行函数的this执行window
	// 自执行函数执行完成后,把执行的结果赋值给对象的属性
	
}

var m = y.z;
m(4);
y.z(5);
console.log(x,y.x)

解析

/* *

程序从上到下执行 遇到var m = y.z; 执行立执行函数,这个函数的this指向window,遇到return,把return返回的地址值赋值给y.z为AAA

所以

this.x *= x

传入的x为全局的x=2;
	window.x = window.x * x = 2 * 2 = 4   此时全局的x = 4

x += 2;

x = x + 2;	传入的是2;  2 + 2 = 4;此时作用域中的x为4(重点)

执行m(4)

相当于执行
    return function(n){
		this.x *= n;
		x += 3;
		console.log(x);
	}

    谁调用this指向谁,此时是window调用
    	window.x  = window.x * n = 4 * 4 = 16
	    x+=3;	x此函数中没有,向上级作用欲中查找为4 ; x+3 = 7

遇到y.z(5)执行,相当于执行之前的AAA(堆内存地址)

return function(n){
	this.x *= n;
	x += 3;
	console.log(x);
}


谁调用this指向谁,此时是y调用,this执行y
	y.x = y.x * n = 3 * 5 = 15;
	x += 3;   x在当前函数中没有,向上级作用域查找,上级作用域的x值为7
	所以x+=3 = 7+3 = 10

cosnole.log(x,y.x);

x = 16

y.x = 15

*/