Heim  >  Artikel  >  Web-Frontend  >  Ist die Pfeilfunktion von ES6 eine funktionale Programmierung?

Ist die Pfeilfunktion von ES6 eine funktionale Programmierung?

青灯夜游
青灯夜游Original
2023-01-11 17:15:401496Durchsuche

Ja. Die Pfeilfunktion ist eine Manifestation der funktionalen Programmierung. Die funktionale Programmierung konzentriert sich mehr auf die Beziehung zwischen Eingabe und Ausgabe und lässt einige Faktoren im Prozess aus. Daher verfügt die Pfeilfunktion nicht über eigene Argumente und neue Ziele (ES6). super (ES6); Pfeilfunktionen entsprechen anonymen Funktionen, daher kann new nicht als Konstruktor verwendet werden.

Ist die Pfeilfunktion von ES6 eine funktionale Programmierung?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, ECMAScript Version 6, Dell G3-Computer.

Pfeilfunktion

Die Pfeilfunktion ist eine neue Funktion, die in ES6 eingeführt wurde und „Pfeil“ (=>) zum Definieren von Funktionen verwendet.

var f = v => v;
// 等同于
var f = function (v) {
  return v;
};

Wenn die Pfeilfunktion keine Parameter oder mehrere Parameter erfordert, verwenden Sie eine Klammer, um den Parameterteil darzustellen.

var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

Wenn der Codeblock der Pfeilfunktion mehr als eine Anweisung enthält, schließen Sie diese mit geschweiften Klammern ein und verwenden Sie die Return-Anweisung, um zurückzukehren.

var sum = (num1, num2) => { return num1 + num2; }

Da geschweifte Klammern als Codeblöcke interpretiert werden, müssen Sie Klammern außerhalb des Objekts hinzufügen, wenn die Pfeilfunktion direkt ein Objekt zurückgibt, andernfalls wird ein Fehler gemeldet.

// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

Das Folgende ist ein Sonderfall. Obwohl es funktioniert, erhalten Sie falsche Ergebnisse.

let foo = () => { a: 1 };
foo() // undefined

Im obigen Code besteht die ursprüngliche Absicht darin, ein Objekt {a:1} zurückzugeben, aber da die Engine denkt, dass die geschweiften Klammern Codeblöcke sind, wird eine Zeile der Anweisung a:1 ausgeführt. Zu diesem Zeitpunkt kann a als Bezeichnung der Anweisung interpretiert werden, sodass die tatsächlich ausgeführte Anweisung 1; ist und die Funktion dann ohne Rückgabewert endet.

Wenn die Pfeilfunktion nur eine Anweisungszeile hat und keinen Wert zurückgeben muss, können Sie die folgende Schreibmethode verwenden, ohne geschweifte Klammern zu schreiben.

let fn = () => void doesNotReturn();

Erläuterung:

Die funktionale Programmierung konzentriert sich mehr auf die Beziehung zwischen Eingabe und Ausgabe und lässt einige Faktoren des Prozesses weg. Daher gibt es in der Pfeilfunktion keine eigene this, arguments, new target (ES6) und super (ES6). Pfeilfunktionen entsprechen anonymen Funktionen, daher kann new nicht als Konstruktor verwendet werden.

Dies in einer Pfeilfunktion zeigt immer darauf im übergeordneten Bereich. Mit anderen Worten: Die Pfeilfunktion erfasst den This-Wert des Kontexts, in dem sie sich befindet, als ihren eigenen This-Wert. Sein Zeiger kann durch keine Methode wie call(), bind(), apply() geändert werden. Wenn dies in einer Pfeilfunktion aufgerufen wird, wird einfach die Bereichskette nach oben durchsucht, um das nächstgelegene this zu finden, und es wird verwendet. Es hat nichts mit dem Kontext des Aufrufs zu tun. Lassen Sie es uns im Code erklären.

Pfeilfunktionen können in Verbindung mit der Variablendestrukturierung verwendet werden

const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
  return person.first + ' ' + person.last;
}

Pfeilfunktionen machen Ausdrücke prägnanter

const isEven = n => n % 2 === 0;
const square = n => n * n;

Der obige Code verwendet nur zwei Zeilen, um zwei einfache Hilfsfunktionen zu definieren. Würde man keine Pfeilfunktionen verwenden, könnte es mehrere Zeilen beanspruchen und wäre nicht so auffällig wie jetzt.

Eine Verwendung von Pfeilfunktionen besteht darin, Rückruffunktionen zu vereinfachen

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);

Ein weiteres Beispiel ist

// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});
// 箭头函数写法
var result = values.sort((a, b) => a - b);

Das Folgende ist ein Beispiel für die Kombination des Restparameters mit der Pfeilfunktion.

const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]

Bei der Verwendung zu beachtende Punkte

Bei der Verwendung von Pfeilfunktionen sind mehrere Punkte zu beachten.

(1) Das Objekt this im Funktionskörper ist das Objekt, in dem es definiert ist, nicht das Objekt, in dem es verwendet wird.

(2) kann nicht als Konstruktor verwendet werden, das heißt, der neue Befehl kann nicht verwendet werden, da sonst ein Fehler ausgegeben wird.

(3) Das Argumentobjekt kann nicht verwendet werden, da das Objekt nicht im Funktionskörper vorhanden ist. Wenn Sie es verwenden möchten, können Sie stattdessen den Rest-Parameter verwenden.

(4) Der Yield-Befehl kann nicht verwendet werden, daher können Pfeilfunktionen nicht als Generatorfunktionen verwendet werden.

Von den oben genannten vier Punkten ist der erste Punkt besonders hervorzuheben. Der Zeiger dieses Objekts ist variabel, aber in einer Pfeilfunktion ist er fest.

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42

Im obigen Code ist der Parameter von setTimeout eine Pfeilfunktion. Die Definition dieser Pfeilfunktion wird wirksam, wenn die foo-Funktion generiert wird, und ihre tatsächliche Ausführung wartet erst 100 Millisekunden später. Wenn es sich um eine normale Funktion handelt, sollte diese bei der Ausführung auf das globale Objektfenster zeigen und zu diesem Zeitpunkt 21 ausgeben. Die Pfeilfunktion bewirkt jedoch, dass dies immer auf das Objekt zeigt, bei dem die Funktionsdefinition wirksam wird (in diesem Fall {id: 42}), sodass die Ausgabe 42 ist.

Mit der Pfeilfunktion kann dies in setTimeout an den Bereich gebunden werden, in dem es definiert ist, anstatt auf den Bereich zu verweisen, in dem es ausgeführt wird. Hier ist ein weiteres Beispiel.

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0

Im obigen Code werden zwei Timer innerhalb der Timer-Funktion eingerichtet, wobei Pfeilfunktionen bzw. normale Funktionen verwendet werden. Die this-Bindung des ersteren ist im Bereich definiert (d. h. die Timer-Funktion), und die this-Bindung des letzteren zeigt auf den Bereich, in dem sie ausgeführt wird (d. h. das globale Objekt). Nach 3100 Millisekunden wurde timer.s1 also dreimal aktualisiert, timer.s2 jedoch kein einziges Mal.

Die Pfeilfunktion kann diesen Punkt fixieren. Diese Funktion ist sehr hilfreich für die Kapselung von Rückruffunktionen. Unten sehen Sie ein Beispiel, bei dem die Rückruffunktion eines DOM-Ereignisses in einem Objekt gekapselt ist.

var handler = {
  id: '123456',
  init: function() {
    document.addEventListener('click',
      event => this.doSomething(event.type), false);
  },
  doSomething: function(type) {
    console.log('Handling ' + type  + ' for ' + this.id);
  }
};

In der Init-Methode des obigen Codes wird eine Pfeilfunktion verwendet, die dazu führt, dass diese in der Pfeilfunktion immer auf das Handler-Objekt zeigt. Andernfalls meldet die Zeile this.doSomething beim Ausführen der Rückruffunktion einen Fehler, da diese zu diesem Zeitpunkt auf das Dokumentobjekt verweist.

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

所以,箭头函数转成 ES5 的代码如下。

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
// ES5
function foo() {
  var _this = this;
  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的this,而是引用外层的this。

请问下面的代码之中有几个this?

function foo() {
  return () => {
    return () => {
      return () => {
        console.log('id:', this.id);
      };
    };
  };
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1

上面代码之中,只有一个this,就是函数foo的this,所以t1、t2、t3都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this,它们的this其实都是最外层foo函数的this。

除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments、super、new.target。

function foo() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]

上面代码中,箭头函数内部的变量arguments,其实是函数foo的arguments变量。

另外,由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

(function() {
  return [
    (() => this.x).bind({ x: 'inner' })()
  ];
}).call({ x: 'outer' });
// ['outer']

上面代码中,箭头函数没有自己的this,所以bind方法无效,内部的this指向外部的this。

长期以来,JavaScript 语言的this对象一直是一个令人头痛的问题,在对象方法中使用this,必须非常小心。箭头函数”绑定”this,很大程度上解决了这个困扰。

【相关推荐:javascript视频教程编程视频

Das obige ist der detaillierte Inhalt vonIst die Pfeilfunktion von ES6 eine funktionale Programmierung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Ist es6 Map ein Referenztyp?Nächster Artikel:Ist es6 Map ein Referenztyp?