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

区别

箭头函数和普通函数之间最关键的区别是this指向问题。普通函数中的 this 指向函数被调用的对象,因此对于不同的调用者,this 的值是不同的。

箭头函数中并没有自己的 this ,所以箭头函数中的 this 是固定的,指向定义函数时所在的对象。

普通函数

var a = 3;
var obj = {
	a:1,
	foo:function(){
		console.log(this.a);
	}
}
obj.foo(); // 1;
var fn = obj;
fn.a = 100;
fn.foo();//100
var f = obj.foo;
f(); // 3

根据这段代码可以知道,普通函数中的 this 总是指向它的调用者,在严格模式下,没找到调用者,函数中的 thisundefined。在非严格模式下,没找到调用者 this 指向 window

var obj = {
	a:1,
	foo:function(){
		setTimeout(function(){
			console.log(this.a,this)
		},100)
	}
}
obj.foo();//undefined,window

这段代码中,setTimeout 中的 function 没被任何对象调用,所以 this 指向还是 window对象。

如果想要将在 setTimeout 中的 this 指向 obj。在箭头函数之前,通常有2种方法。

定义一个临时变量
在 foo 函数的内部,通过定义一个变量 that 来保存当时的 this

var obj = {
	a:1,
	foo:function(){
		var that = this;
		setTimeout(function(){
			console.log(that.a,that)
		},100)
	}
}
obj.foo();//1, {a: 1, foo: ƒ}

使用bind()来绑定this

var obj = {
	a:1,
	foo:function(){
		setTimeout(function(){
			console.log(this.a,this)
		}.bind(this),100)
	}
}
obj.foo();//1, {a: 1, foo: ƒ}

箭头函数

箭头函数是 ES6 中引入的新特性。箭头函数表达式的语法比函数表达式要简洁,并且没有自己的 thisargumentssupernew.target。更适于那些本来需要匿名的函数,并且箭头函数不可以作为构造函数。其语法为:

(参数1,参数2,...,参数N) =>{ 函数体 }

// 相当于(参数1,参数2,...,参数N) =>{ return 表达式; }
(参数1,参数2,...,参数N) => 表达式(单一)

//当只有1个参数,可忽略()
(参数)=>{ 函数体 }
参数 =>{ 函数体 }

//没有参数的函数写成一个()
()=>{ 函数体 }

高级语法
返回对象字面量表达式
params=>{object: literal} 这种简单的语法返回对象字面量是行不通的。

var func = ()=>{ obj: 1 }; // 调用 func() 返回 undefined
var func = ()=>{ foo: function(){} } //Function statements require a function name

这是因为花括号 {} 里面的代码被解析为一系列语句 ( foo 被认为是一个标签,而非对象字面量的组成部分 )。所以不要忘记用 ( ) 把对象字面量包括起来。

name=>({obj:name})

支持剩余参数和默认参数

(参数1, 参数2, ...rest) => {函数声明}
(参数1 = 默认值1,参数2,, 参数N = 默认值N) => {函数声明}

支持参数解构

let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6

箭头函数有2个方面的作用: 简短的函数和不绑定this
简短的函数

var ary = [1,2,3,4];
ary.map(item=>{
	return item
})// [1, 2, 3, 4]

箭头函数式闭包

var add = (i=0)=>{ return (()=>(i+10))}
add(10)(); // 20

不绑定 this
箭头函数不会自己创建 this,只会从自己作用域链的上一层继承 this,因此下面 setTimeout 里面函数的 this 和 foo 函数的 this 是相同的。

var a = 100;
var obj = {
	a:1,
	foo:function(){
		setTimeout(()=>{
			console.log(this.a,this); //正确的执行当前函数执行的上下文
		},100)
	}
}
obj.foo();//1,{a: 1, foo: ƒ}

没有 arguments 对象

	let u = ()=>{
	console.log(arguments)
}
u(1,2,3); // arguments is not defined

function foo(n) {
  var f = () => arguments[0] + n; // 隐式绑定 foo 函数的 arguments 对象. arguments[0] 是 n
  return f();
}
foo(1); //2

不能够使用 new 操作符

let B = ()=>{}
let b = new B(); // B is not a constructor

没有 prototype 属性

let B = ()=>{}
B.prototype; // undefined

yield 关键字通常也不在箭头函数中使用( 除非是嵌套的在允许使用的函数内 ),所以箭头函数不能用作生成器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值