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

1、箭头函数语法更加简洁、清晰

箭头函数的定义要比普通函数定义简洁、清晰得多,很快捷。

(1)、箭头函数体只有一个参数时,可以省略圆括号;

(2)、箭头函数没有function关键字;

(3)、箭头函数在函数体中只有return返回语句或者只有一句代码,return和{}可以省略。

2、箭头函数不会创建自己的this

箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this。

 箭头函数没有自己的this,它会捕获自己在定义时(注意,是定义时,不是调用时)所处的父作用域的this,并继承这个this值。所以,箭头函数中this的指向在它被定义的时候就已经确定了,之后永远不会改变。

来看个例子:

 function fun1() {
            // setTimeout中使用普通函数
            setTimeout(function () {
                console.log(this);
            }, 1000);
        }

        function fun2() {
            // setTimeout中使用箭头函数
            setTimeout(() => {
                console.log(this);
            }, 1000)
        }

        fun1()//Window
        fun1.call({ obj: 123 });//Window

        fun2()//Window
        fun2.call({ obj: 123 });//{obj: 123}

 上面这个例子,函数fun1中的setTimeout中使用普通函数,1秒后函数执行时,这时函数其实是在全局作用域执行的,所以this指向Window对象。
但是函数fun2中的setTimeout中使用的是箭头函数,这个箭头函数的this在定义时就确定了,它继承了它外层fun2的执行环境中的this,而fun2调用时thiscall方法改变到了对象{id: 'Obj'}中,所以输出'Obj'

3、.call()/.apply()/.bind()无法改变箭头函数中this的指向

.call()/.apply()/.bind()方法可以用来动态修改函数执行时this的指向,但由于箭头函数的this定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this的指向

let obj = {
            a: 1,
            b: function () {
                console.log(this)//{a: 1, b: ƒ}
                return () => {
                    console.log(this);
                }
            }
        }
        obj.b()()//{a: 1, b: ƒ}

        // this的指向不会改变
        obj.b().call({ obj: 123 });     // {a: 1, b: ƒ}
        obj.b().apply({ obj: 123 });    // {a: 1, b: ƒ}
        obj.b().bind({ obj: 123 })();   // {a: 1, b: ƒ}

 4、箭头函数不能作为构造函数使用

我们先了解一下构造函数的new都做了些什么?简单来说,分为四步:

① JS内部首先会先生成一个对象;

② 再把函数中的this指向该对象;

③ 然后执行构造函数中的语句;

④ 最终返回该对象实例。

但是!!因为箭头函数没有自己的this,它的this其实是继承了父作用域中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错!

let Fun = (name, age) => {
            this.name = '张三';
            this.age = 18;
        };

        let obj = new Fun('cao', 24);//报错:Fun is not a constructor

 5、箭头函数没有原型prototype

let sayHi = () => {
    console.log('Hello World !')
};
console.log(sayHi.prototype); // undefined

6、箭头函数没有自己的arguments

箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是父作用域(函数)的值。

// 例子一
let fun = (val) => {
    console.log(val);   // 111
    // 下面一行会报错
    // Uncaught ReferenceError: arguments is not defined
    // 因为外层全局环境没有arguments对象
    console.log(arguments); 
};
fun(111);

// 例子二
function outer(val1, val2) {
    let argOut = arguments;
    console.log(argOut);    // ①
    let fun = () => {
        let argIn = arguments;
        console.log(argIn);     // ②
        console.log(argOut === argIn);  // ③
    };
    fun();
}
outer(111, 222);

上面例子二,①②③处的输出结果如下:

很明显,普通函数outer内部的箭头函数fun中的arguments对象,其实是沿作用域链向上访问的外层outer函数的arguments对象。

你可能感兴趣的:(javascript,前端,vue.js)