简单说 JavaScript的箭头函数

说明
箭头函数本质还是函数,我们来看看他与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 的指向 可能和你想的不一样

window.name='window';
var obj = {
    name:'obj',
    show_name:() =>{
        console.log(this.name);
    }   
}
obj.show_name(); //window

JavaScript使用的是函数作用域,在上面这段代码中对象的括号是不能封闭作用域的,所以此时的this还是指向window。
我们换成普通函数看看

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 值。

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

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 的指向。

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 不可变

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参数,剩余参数,不了解的朋友看这里
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters

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对象。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容