← 返回首页
Js中箭头函数与普通的区别
发表时间:2022-08-26 17:53:05
Js中箭头函数与普通的区别

Javascript中箭头函数与普通的函数的区别。

1.箭头函数与普通函数

箭头函数(arrow functions),是一个来自ECMAScript 2015(又称ES6)的全新特性。箭头函数有时候也叫“lambda表达式”。箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

以上是箭头函数的官方解释,简单说箭头函数就是匿名函数,为了简化了函数定义。

//普通函数
function fun(){
    console.log('我是普通函数...');
}

//箭头函数
let arrFun = ()=>console.log('我是箭头函数...');

fun();
arrFun();

运行结果:

我是普通函数...
我是箭头函数...

2.箭头函数的两种形式

箭头函数有两种格式,一种只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return。

//只包含一个表达式的箭头函数
let fun = ()=>console.log('我是箭头函数...');

//包含{ ... }和return的箭头函数
let add = (x,y)=>{
    let z = x+y;
    return{
        result: z
    }
}
fun();
console.log(add(5,7));

运行结果:

我是箭头函数...
{ result: 12 }

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

箭头函数与普通函数的最大区别,体现在以下三点:

下来咱们分别探讨。

1)箭头函数不能作为构造函数使用;普通函数可以作为构造函数使用。

function Fun(){
   console.log('Fun()...');
}

let ArrowFun = ()=>{
   console.log('ArrowFun()...');
}

let f = new Fun();
//TypeError: ArrowFun is not a constructor
let fn = new ArrowFun(); //错误

2)箭头的this指向永远不变,普通函数中的this代表调用当前方法的对象。

<script>
    var name = 'window'
    function fun(){
        console.log('in Fun=>'+this.name);
    }
    let arrowFun = ()=>{
        console.log('in ArrowFun=>'+this.name);
    }
    fun();
    arrowFun();
</script>

运行结果:

in Fun=>window
in ArrowFun=>window

因为此时name是绑定在window对象上,而调用者两个方法默认都是window对象,所以无论是箭头函数还是普通函数的this都是指向window。

改写如下:

<script>
    var name = 'window'
    function fun(){
        console.log('in Fun=>'+this.name);
    }
    let arrowFun = ()=>{
        console.log('in ArrowFun=>'+this.name);
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        arrowFun: arrowFun
    }
    person.fun();
    person.arrowFun();
</script>

运行结果:

in Fun=>zhangsan
in ArrowFun=>window

此时fun()里的this指向调用当前方法的那个对象,当然是person对象,所以fun()里的this指向person对象。而箭头函数里的this永远指向window对象。

有小伙伴会问:如果把arrowFun定义到person对象里面,情况会变化吗?答案是否定的。

<script>
    var name = 'window'
    function fun(){
        console.log('in Fun=>'+this.name);
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        arrowFun: ()=>{
            console.log('in ArrowFun=>'+this.name);
        }
    }
    person.fun();
    person.arrowFun();
</script>

运行结果:

in Fun=>zhangsan
in ArrowFun=>window

这里一定要理解,箭头函数里的this永远绑定自己的上一层作用域对象的this,但是对象不构成作用域。我们把程序改写如下:

<script>
    var name = 'window'

    function fun() {
        console.log('in Fun=>' + this.name);
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        myFn: function () {
            let arrowFun = () => {
                console.log('in ArrowFun=>' + this.name);
            }
            arrowFun();
        }
    }

    person.fun();
    person.myFn();
</script>

运行结果:

in Fun=>zhangsan
in ArrowFun=>zhangsan

此时,箭头函数在一个普通函数内部,所以this指向会指向person对象。

但是如果咱们把myFn属性改为对象属性,因为对象不构成作用域,则箭头函数的this指向还是指向window对象。

<script>
    var name = 'window'
    function fun() {
        console.log('in Fun=>' + this.name);
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        myFn: {
            arrowFun: () => {
                console.log('in ArrowFun=>' + this.name);
            }
        }
    }
    person.fun();
    person.myFn.arrowFun();
</script>

运行结果:

in Fun=>zhangsan
in ArrowFun=>window

需要注意的是,如果箭头函数在另一个箭头函数里面,那么作用域还是不会改变。

<script>
    var name = 'window'

    function fun() {
        console.log('in Fun=>' + this.name);
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        myFn: () => {
            let arrowFun = () => {
                console.log('in ArrowFun=>' + this.name);
            }
            arrowFun();
        }
    }
    person.fun();
    person.myFn();
</script>

运行结果:

in Fun=>zhangsan
in ArrowFun=>window

即便使用call(),apply(),bind()也无法改变箭头函数中this的指向。

<script>
    var name = 'window'
    function fun() {
        console.log('in Fun=>' + this.name);
    }

    let lisi = {
        name: 'lisi'
    }

    let person = {
        name: 'zhangsan',
        fun: fun,
        myFn: function () {
            let arrowFun = () => {
                console.log('in ArrowFun=>' + this.name);
            }
            arrowFun.call(lisi);
        }
    }
    person.fun.call(lisi);
    person.myFn();
</script>

运行结果:

in Fun=>lisi
in ArrowFun=>zhangsan

小结:箭头函数里的this永远绑定自己的上一层作用域对象的this,但是有两种情况除外:1.对象不构成新的作用域。2.箭头函数在另一个箭头函数里面。

3)箭头函数没有自己的arguments

<script>
    let add = ()=>{
        console.log(arguments)
    }
    add(1,2,3)
</script>

运行结果:

Uncaught ReferenceError: arguments is not defined

普通函数有自己的arguments

<script>
   function add(){
       console.log(arguments);
   }

   add(1,2,3)
</script>

运行结果:

Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

但是箭头函数可以使用展开语法获取参数。

<script>
    let add = (...args)=>{
        console.log(args)
    }
    add(1,2,3)
</script>

运行结果:

(3) [1, 2, 3]

小结:

箭头函数与普通函数的最大区别,体现在以下三点:

注意:箭头函数在对象里面,或者箭头函数在另一个箭头函数里面都不构成新的作用域。