说明
箭头函数本质还是函数,我们来看看他与JavaScript中普通函数的区别,先看看写法上的区别。
解释
写箭头函数,我们记住一个顺序就好,参数、箭头、函数体、这个顺序记住就足够了,参数、箭头、函数体、这三个是必须的,函数名可以没有,但这三项必须有,一些简写的方式也是简写这三项里的东西。
简写
1、只有一个参数时,()
可省略
//不简写
var demo = (x) =>{
console.log(x);
}
//简写
var demo = x =>{
console.log(x);
}
2、函数体只有一句时, {}
可以省略
//不简写
var demo = (x) =>{
console.log(x);
}
//简写
var demo = x => console.log(x);
3、函数体只有一条返回语句时,{}
和 return 都可以省略
//不简写
var demo = (x) => {
return x;
}
//简写
var demo = (x) => x;
//注意别写成这样
var demo = (x) =>{ x };
//或者 这样
var demo = (x) => return x;
//要省略就都省略,不省略就都不省,别省一半,不然会出错的。
注意:
箭头函数放 参数 的地方就在 ()
内,
没有参数,()
必须写,
一个参数,()
可写可不写,
多个参数,()
必须写。
箭头函数放 函数体 的地方在 {}
内,
函数体 就 一句 {}
可写可不写,
函数体 不止一句,{}
必须写。
如果不知道,() {}
写不写,该不该省略,那就写,写了不会错。
箭头函数 如果要返回一个对象,要简写的话, 需要用()
包住这个对象
//不简写
var demo = () =>{
return {x:1};
}
//简写
var demo = () =>({x:1});
为什么会这样?因为如果不加 () ,那{ } 就表示的是语法块,不是表示一个对象,而加上(),按照规范来说,() 里面 { } 就会被解析为对象了。
对于 {x:1}
这个情况,他不仅可以表示一个对象,这个对象有个x属性,值为1,也可以表示为语法块中含有 名为 x 的 label,忘记 label语法的话,可以看这里
如果不是很明白,可以看看这个回答,应该会理解的更加深刻。
https://www.zhihu.com/question/40902815
所以这也解释了为什么会出现下面代码中的情况
// 不报错
var demo = () =>{x:1};
// 报错
var demo = (y) =>{y,x:1};
对象的方法用 箭头函数写时,this 的指向 可能和你想的不一样
代码语言:javascript复制window.name='window';
var obj = {
name:'obj',
show_name:() =>{
console.log(this.name);
}
}
obj.show_name(); //window
JavaScript使用的是函数作用域,在上面这段代码中对象的括号是不能封闭作用域的,所以此时的this还是指向window。 我们换成普通函数看看
代码语言:javascript复制window.name='window';
var obj = {
name:'obj',
show_name: function (){
console.log(this.name);
}
}
obj.show_name(); //obj
换成普通函数,this 就不是指向window,而是指向 obj 对象了
箭头函数 与 普通函数 其他的区别
1、箭头函数没有自己的this。箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值。 2、箭头函数 this 不可变。call()、apply()、bind()、这些方法也 无法改变 箭头函数 this 的指向。 3、箭头函数 不能用 new 关键字来实例化对象,不然会报错。 4、箭头函数没有arguments对象。
1、箭头函数没有自己的this。箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值。
代码语言:javascript复制window.name = 'window';
var obj = {
name:'obj',
show_name:function (){
function fn (){
console.log(this.name);
}
fn();
},
}
obj.show_name(); // window
声明一个 obj 对象,有一个name
属性 与 show_name
方法,上面这段代码,我的本意是想显示 obj对象的name
, 但是没和我想的一样,一般我们会用 一个变量 self
或者 that
之类的留住this
,像这样
window.name = 'window';
var obj = {
name:'obj',
show_name:function (){
//留住this
var that = this;
function fn (){
console.log(that.name);
}
fn();
},
}
obj.show_name(); //obj
通常来说,箭头函数内部的this就是外层代码块的this
代码语言:javascript复制window.name = 'window';
var obj = {
name:'obj',
show_name:function (){
var fn = () => {
console.log(this.name);
}
fn();
},
}
obj.show_name(); //obj
2、箭头函数 this 不可变。call()、apply()、bind()、这些方法也 无法改变 箭头函数 this 的指向。
代码语言:javascript复制window.name = 'window';
var obj = {
name:'obj',
}
function show_name(){
//这里 show_name 是一个普通的全局函数,所以他的this指window
console.log(this.name);
}
//用了 call 方法,把 show_nam 的this 指向了 obj 对象
show_name.call(obj); //obj
箭头函数 this 不可变
代码语言:javascript复制window.name = 'window';
var obj = {
name:'obj',
}
var show_name = () => {
//这里 show_name 是箭头函数,他的this指window,并且不会变
console.log(this.name);
}
//用了 call 方法,但是 this 没变,所以打印了 window
show_name.call(obj); //window
3、箭头函数 不能用 new 关键字来实例化对象,不然会报错,箭头函数的this 不可变,new 也改变不了 this的 指向,而且更为重要的是,箭头函数内部并没有 [[Construct]] 方法,所以会没有原型属性(prototype),所以箭头函数没法当构造函数。
4、箭头函数没有arguments对象,不能通过arguments对象访问传入参数,但是可以用rest参数实现 rest参数,剩余参数,不了解的朋友看这里
代码语言:javascript复制var demo = (...theArgs) => theArgs;
demo(1,2,3); //[1,2,3]
总结
在来看一遍 箭头函数 与 普通函数,除了写法上的区别
1、箭头函数没有自己的this。箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值。 2、箭头函数 this 不可变。call()、apply()、bind()、这些方法也 无法改变 箭头函数 this 的指向。 3、箭头函数 不能用 new 关键字来实例化对象,不然会报错。 4、箭头函数没有arguments对象。
可以看出,最重要的区别还是 在 this 上,所以要想用好 箭头函数,还是要对 this 有一定认识的,朋友们继续努力吧!