Heim  >  Artikel  >  Web-Frontend  >  Tiefes Verständnis der Funktionen in JavaScript

Tiefes Verständnis der Funktionen in JavaScript

黄舟
黄舟Original
2017-03-02 14:56:271312Durchsuche

Dieser Artikel soll Grundkenntnisse aller JavaScript-Funktionen vermitteln, die ein Webentwickler kennen muss.

Funktionen sind keine Fantasiewelt für Softwareentwickler. Wenn Ihre täglichen Aktivitäten auch nur ein bisschen Programmieren beinhalten, müssen Sie am Ende des Tages eine oder mehrere Funktionen erstellt/geändert haben.

Kurz gesagt ist eine Funktion nur eine Reihe von Anweisungen, die eine bestimmte Operation ausführen. Eine Funktion kann einige Eingabeparameter haben (die im Funktionskörper verwendet werden) und nach der Ausführung einen Wert zurückgeben.

JavaScript-Funktionen verfügen ebenfalls über diese Eigenschaften, es handelt sich jedoch nicht nur um reguläre Funktionen. JavaScript-Funktionen sind Objekte. Sie können den Artikel lesen, den ich einmal über JavaScript-Objekte geschrieben habe, in dem ich erwähnt habe, dass fast alles in JavaScript ein Objekt ist.

JavaScript-Funktionen können als Objekte Eigenschaften und andere Funktionen (Methoden) haben. Werfen wir einen Blick auf eine typische Funktionsdefinition in JavaScript.

function myNotSoGreatFunc(visitor) {
   console.log("Welcome to Code Morning Mr. " + visitor);
}

Das stimmt. Die obige Funktion beinhaltet nichts Großartiges, da sie lediglich die Besucher des Blogs willkommen heißt. Aber es zeigt, wie JavaScript-Funktionen aussehen. Eine Funktionsdefinition beginnt mit dem Schlüsselwort function, gefolgt vom Funktionsnamen, leer oder Klammern mit Parametern. Der eigentliche Funktionscode (JavaScript-Anweisung) ist in ein Paar geschweifte Klammern { } eingeschlossen. Für Funktionen ist die return-Anweisung optional. JavaScript-Funktionen geben immer einen Wert zurück. Wenn im function-Körper keine return-Anweisung vorhanden ist, gibt function undefiniert zurück.

Der folgende Code ruft eine Funktion auf, die den Besuchernamen als Parameter übergibt.

myNotSoGreatFunc("Bob Martin");
// Output: 
// Welcome to Code Morning Mr. Bob Martin.

Bisher verstehen wir die grundlegenden Eigenschaften von Funktionen. Nun werfen wir einen Blick auf einige fortgeschrittene Konzepte von JavaScript-Funktionen.

Anonyme Funktionen

JavaScript-Funktionen können anonym sein. Das bedeutet, dass Sie den Funktionsnamen in der Funktionsdeklaration weglassen können. Funktionen müssen jedoch in Variablen gespeichert werden.

var addNumbers = function (x, y) { return x + y; }

Die obige Syntax wird auch als Funktionsausdruck bezeichnet. Sie können die Variable addNumbers als Funktionsnamen verwenden und die Funktion wie unten beschrieben aufrufen.

var sum = addNumbers(2, 3);

Funktionsausdrücke sind sehr praktisch, wenn Sie eine Funktion als Parameter an eine andere Funktion übergeben möchten. Versuchen wir dies anhand eines einfachen Beispiels zu verstehen.

var add = function (first, second) { return first + second };
var multiply = function (first, second) { return first * second };

function calculate(fun, a, b) {
    return fun(a, b);
}

Zuerst habe ich zwei anonyme Funktionen erstellt. Der erste gibt die Addition zweier Zahlen zurück und der zweite gibt die Multiplikation zweier Zahlen zurück. Ziemlich einfach, nichts zum Vorzeigen. Dann definiere ich die Funktion calculate, die eine Funktion als erstes Argument akzeptiert, gefolgt von zwei Argumenten, die zwei Zahlen akzeptieren.

Ich kann die Funktion berechnen aufrufen, indem ich eine beliebige Funktion als erstes Argument übergebe.

var sum = calculate(add, 2, 3); // sum = 5
var multiplication = calculate(multiply, 2, 3); // multiplication = 6

Sie können sehen, wie einfach es ist, Funktionen als Argumente zu übergeben. Dieses Muster wird in AJAX häufig verwendet, wenn Sie eine Rückruffunktion übergeben, um Erfolgs- oder Fehlerszenarien zu behandeln, nachdem der AJAX-Aufruf abgeschlossen ist.

Mehr über Parameter

JavaScript ist sehr flexibel, wenn es um die Übergabe oder den Zugriff auf Funktionsparameter geht. Schauen wir uns an, wie Funktionsparameter manipuliert werden können.

Fehlende Parameter

Wenn eine Funktion aufgerufen wird, kann die Funktion weniger oder mehr Parameter als erforderlich haben. Wenn Sie eine Funktion mit weniger Argumenten als deklariert aufrufen, werden die fehlenden Argumente auf undefiniert gesetzt.

function callMe(a, b, c) {
   console.log("c is " + typeof c);
}

callMe("Code", "Morning"); 
// Output: "c is undefined"
callMe("Learn", "JavaScript", "Functions"); 
// Output: "c is string"

Argumentobjekt

Alle JavaScript-Funktionen verfügen über ein spezielles Objekt namens arguments, bei dem es sich um das Argumentarray handelt, das während des Funktionsaufrufs übergeben wird. Dieses Objekt kann verwendet werden, um auf einzelne Parameter zuzugreifen oder die Gesamtzahl der an eine Funktion übergebenen Parameter abzurufen.

function callMe() {
   var i;
   for (i = 0; i < arguments.length; i++) {
      console.log(arguments[i]);
   }
   console.log("Total arguments passed: " + arguments.length);
}

Diese Funktion geht davon aus, dass keine Parameter übergeben werden, aber wie gesagt, Sie können einer JavaScript-Funktion eine beliebige Anzahl von Parametern übergeben. Ich kann diese Funktion wie folgt aufrufen:

callMe("Code", "Morning", "Mr. Programmer");
// Output":
// Code
// Morning
// Mr. Programmer
// Total arguments passed: 3

Auf jedes Argument kann als Array-Element vom arguments-Objekt aus zugegriffen werden. Die Gesamtzahl der an die Funktion übergebenen argumentss ist über die Eigenschaft arguments.length verfügbar.

Standardparameter

Sind Sie ein C++- oder C#Programmierer? Haben Sie schon einmal eine Funktion gesehen, die Standardparameter verwendet? Vielleicht antworten Sie ja! ECMAScript 6 bietet diese Funktion von JavaScript, d. h. Sie können Funktionen mit Standardparametern definieren.

function greetMyVisitors(name, profession = "The cool programmer") {
    alert("Welcome Mr. " + name + ", " + profession);
}

Diese Funktion begrüßt Blog-Besucher höflich. Es verfügt über zwei Parameter name und profession und zeigt eine Willkommensnachricht im Meldungsfeld an. Wenn beim Aufruf keine Argumente (oder „undefiniert“) übergeben werden, nimmt das zweite Argument den Standardwert an.

greetMyVisitors("Justin Bieber", "The singer"); 
// Shows the message "Welcome Mr. Justin Bieber, The singer"

greetMyVisitors("Bob Martin"); 
// Shows the message "Welcome Mr. Bob Martin, The cool programmer"

greetMyVisitors("John Papa", undefined); 
// Shows the message "Welcome Mr. John Papa, The cool programmer"

Verschachtelte Funktionen

Eine Funktion kann eine oder mehrere Funktionen enthalten. Innere Funktionen können intern wieder Funktionen enthalten. Werfen wir einen Blick auf die folgenden Vorgänge.

function wakeUpAndCode() {
   function wakeUp() {
      console.log("I just woke up");
   }

   function code() {
      console.log("I am ready to code now");
   }

   wakeUp();
   code();
}

wakeUpAndCode();

// Output:
// I just woke up
// I am ready to code now

函数wakeUpAndCode包含两个内部函数wakeUp和code。当调用wakeUpAndCode时,函数主体开始执行函数主体。在外部函数中只有两个可执行语句,调用wakeUpcode的方法。调用wakeUp将执行内部wakeUp函数,这将写入string“I just woke up”到控制台。调用code将会写入“I am ready to code now”string到控制台。

内部函数可以访问所有外部函数的变量和参数。内部函数是函数内部某种private实现,并且不能从外部函数以外被调用。内部函数的使用生成了JavaScript闭包,这个我将另起一篇文章讨论。

立即执行函数表达式(IIFE,发音iffy)

IIFE是被立即调用执行的匿名函数表达式。IIFE看上去像这样:

(function() {
   // Your awesome code here
}());

所有你要做的就是创建一个匿名函数,在函数定义后马上放一对圆括号以调用函数,最后将所有代码封装在另一对圆括号中。最外层的括号将它里面的所有一切转变成一个表达式,因为括号不能包含JavaScript语句。函数定义后面的圆括号则立即调用函数。

IIFE块中定义的任何变量或函数对块而言是本地的,并且不能被这个范围以外的任何代码改变。

看看IIFE的这个例子。此函数没有调用也会自动执行。

(function() {
   console.log("I run on my own.");
}());

只需在plunker中复制并粘贴代码,看看在浏览器控制台中的输出。如果你不知道去哪里找浏览器控制台,那么只要在浏览器窗口中按下F12就会出现开发者工具。跳转console选项卡以查看console.log语句的所有输出。

IIFE是一个在代码中创建局部范围的很好方法。它们可以帮助你保护变量和函数,以避免被应用程序的其他部分更改或覆盖。JavaScript中IIFE的其他优势?它们是如何解决全局范围污染问题的?欢迎点击查看我关于立即执行函数表达式的文章。

构造函数

函数可以充当构造器的角色,并且可以使用构造函数来创建新的对象。这是使JavaScript面向对象的特点之一。使用构造函数的好处是,你将能够通过预定义的属性和方法,创造尽可能多的对象。如果你由此关联到其他语言中的类和对象,那么你做的对。

让我们创建一个带有一些属性和方法的构造函数Programmer。你可以假设它在你最喜欢的语言中是一个类。

function Programmer(name, company, expertise) {
   this.name = name;
   this.company = company;
   this.expertise = expertise;

   this.writeCode = function() {
      console.log("Writing some public static thing..");
   }

   this.makeSkypeCall = function() {
      console.log("Making skype call..");
   }

   this.doSalsa = function() {
      console.log("I&#39;m a programmer, I can only do Gangnam style..");
   }

   this.canWriteJavaScript = function() {
      return expertise === "JavaScript";
   }
}

函数有三个参数,并创建了一个具有三个属性和四种方法的对象。我不认为上面的代码需要任何解释。此外,我可以创建任意数量程序员对象。

var javaProgrammer = new Programmer("Mohit Srivastava", "Infosys", "Java");
var dotnetProgrammer = new Programmer("Atul Mishra", "Prowareness", ".NET");

虽然也可以创建一个使用对象文本语法带有相同属性和方法的对象,但我们需要多次编写相同的代码,这可不是什么伟大的实践。如果你知道编程DRY原则,那么你就不会不赞同我。构造函数使得可以一次定义对象,并创建真正的实例,无论什么时候你想要。

警告!

始终使用new关键字来从构造器创建新的对象。忘记了new而像这个创建一个实例->

var jsProgrammer = Programmer("Douglas Crockford", "Yahoo", "JavaScript")

最终将添加所有属性和方法到全局的window对象,哇哦,这将是太可怕了。原因是,除非明确指定,否则“this”指向全局的window对象。使用new 设置“this”上下文到被创建的当前对象。

然而,有一种变通方法可以来克服这个问题。你可以改变构造函数的实现以使域安全,然后在创建新的对象时,你就可以愉快地忽略new 关键字了。请参见以下修改了的构造函数代码。为了便于查看,我已删除了一些方法。

function Programmer(name, company, expertise) {
   if(!(this instanceof Programmer)) {
      return new Programmer(name, company, expertise);
   }

   this.name = name;
   this.company = company;
   this.expertise = expertise;

   this.writeCode = function() {
      console.log("Writing some public static thing..");
   }
}

if 条件检查了this 对象是否是Programmer的一个实例。如果不是,它会创建一个新的Programmer对象,并通过再次调用构造器返回相同的内容。

注意:你无法在不使用’new’关键字的情况下,在Strict模式下从构造器创建一个新的对象。Strict模式强制一些编码准则,并且在你写的东西不安全的情况下会抛出错误。要启用Strict模式,你只需要添加在你的代码开头添加字符串 ‘use strict’。在Strict模式下运行代码是一个良好的实践。

&#39;use strict&#39;
 function doSomething() { ... }
 ....
 ....

在这篇文章中,我几乎已经涵盖了有关函数的所有内容。函数被认为是JavaScript中的一等公民。理解函数可能是最重要的事情,如果你想掌握JavaScript的话。

欢迎各位指正。

Das Obige ist der Inhalt eines umfassenden Verständnisses der Funktionen in JavaScript. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!

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