箭头函数与一般函数有啥区别?

ES6遍及后,箭头函数越来越多的呈现在咱们的日常开发中,那么箭头函数与一般函数到底由什么区别呢?

波及相干知识点

  • new操作符
  • new.target
  • prototype
  • 浏览器事件
  • Object.prototype.defineProperty
  • call、bind、apply
  • prototype
  • arguments对象

this绑定

箭头函数没有本人的this,它会从本人的作用域链的父级继承this

为了更好的了解下面的这段话,咱们来举几个例子

如何了解无this绑定?

例子1:页面的事件回调函数

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <title>事件回调中函数的this</title>  </head>  <body>    <button id="arrow-function">箭头函数</button>    <button id="regular-function">一般函数</button>  </body>  <script>    const arrowFunctionButton = document.querySelector("#arrow-function");    const regularFunctionButton = document.querySelector("#regular-function");    arrowFunctionButton.addEventListener("click", () => {      console.log(this); // this指向window ①    });    regularFunctionButton.addEventListener("click", function () {      console.log(this); // this指向以后的点击元素 ②    });        function Wrapper() {      let arrowFunction = () => {        console.log('我是被包裹箭头函数的this >>>', this);      }        document.addEventListener('click', arrowFunction);    }        let object = new Wrapper(); // ③  </script></html>

让咱们再来回顾一遍箭头函数中this的个性

箭头函数没有本人的this,它会从本人的作用域链的父级继承this。

因而在①中,这个回调函数作用域链的父级是window,因而打印进去的后果是window

事件回调的函数如果是一般函数,此时this将会指向以后被点击的元素,因而②中打印出的后果是<button id="regular-function">一般函数</button>

执行后果如下:

请留神,箭头函数会依据应用地位而不是定义地位继承词法作用域。当应用new运算符时,像执行对象的构造函数那样来执行函数。因而函数外部的每条语句都将在实例化对象object的语境中执行,而不是在window的语境中执行。因而在③中,咱们能够晓得,this指向实例化的object

执行后果如下:

例子2:Object.prototype.defineProperty办法

上面是一个来自MDN的例子,解释了为何咱们很少看见在definePrototype中应用箭头函数

var obj = {  a: 10};Object.defineProperty(obj, "b", {  get: () => {    console.log(this.a, typeof this.a, this); // this指向window    return this.a+10;  }});obj.b; // NaN

执行后果如下:

因为箭头函数的this指向window,而window内并未定义a属性,因而:
this等价于windowthis.a等价于undefined,而this.a + 10实际上等价于undefined + 10后果为NaN

callapplybind调用将会疏忽第一个参数

window.a = 1;const obj = {  a: 2};const uselessCall = (arg) => {  console.log('我是this >>>', this, '我是this.a >>>', this.a, '我是传入值 >>>', arg);}function usefulCall (arg) {  console.log('我是this >>>', this, '我是this.a >>>', this.a, '我是传入值 >>>', arg);}uselessCall.call(obj, 10);usefulCall.call(obj, 10);

执行后果如下:

因为箭头函数没有本人的this,将会导致通过callapplybind调用一个箭头函数时,疏忽第一个参数。当没有指定第一个参数时,将会默认绑定window。前面传入的参数仍旧无效。

arguments对象

箭头不绑定arguments对象,一般函数绑定arguments对象。

如果你在箭头函数中想要拜访arguments对象,将会产生援用谬误:

const noArguments = () => console.log(arguments);noArguments();

执行后果如下:

在一般函数中,咱们能够应用arguments对象

function hasArguments() {  console.log(arguments);}hasArguments();

执行后果如下:

小提示
如果你心愿在箭头函数中获取函数传入参数,请间接应用残余参数来获取

const restParameters = (...args) => console.log(args);

无构造函数

应用new操作符报错

箭头函数不能用于结构,因而应用new将会报错

const ErrorNew = () => {};new ErrorNew;

执行后果如下:

new.target

因为无奈被new运算符调用,因而箭头函数同样不领有new.target

const noNewTarget = () => console.log(new.target);

执行后果如下:

prototype属性

箭头函数没有prototype属性,如果试图设置prototype属性,将会报错!

const NoPrototype = () => {};console.log(NoPrototype.prototype); // undefinedNoPrototype.prototype.age = 11; // 抛出谬误

执行后果如下: