10

说明

箭头函数本质还是函数,我们来看看他与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/questio...
所以这也解释了为什么会出现下面代码中的情况

// 不报错
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参数,剩余参数,不了解的朋友看这里

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 有一定认识的,朋友们继续努力吧!


FEWY
4.7k 声望443 粉丝