Lernen Sie diese JavaScript-Grundlagen und werden Sie ein besserer Entwickler

Discover Functional JavaScript wurde von BookAuthority als eines der besten neuen funktionalen Programmierbücher ausgezeichnet !

JavaScript hat Grundelemente, Objekte und Funktionen. Alle von ihnen sind Werte. Alle werden als Objekte behandelt, auch als Grundelemente.

Primitive

Zahl, Boolescher Wert, Zeichenfolge undefinedund nullsind Grundelemente.

Nummer

In JavaScript gibt es nur einen Zahlentyp, den 64-Bit-Binärgleitkommatyp. Die Arithmetik der Dezimalzahlen ist ungenau.

Wie Sie vielleicht bereits wissen, 0.1 + 0.2macht nicht 0.3. Aber mit ganzen Zahlen ist die Arithmetik genau 1+2 === 3.

Zahlen erben Methoden vom Number.prototypeObjekt. Methoden können auf Zahlen aufgerufen werden:

(123).toString(); //"123" (1.23).toFixed(1); //"1.2"

Es gibt Funktionen zum Konvertieren von Zeichenfolgen in Zahlen : Number.parseInt(), Number.parseFloat()und Number():

Number.parseInt("1") //1 Number.parseInt("text") //NaN Number.parseFloat("1.234") //1.234 Number("1") //1 Number("1.234") //1.234

Ungültige arithmetische Operationen oder ungültige Konvertierungen lösen keine Ausnahme aus, führen jedoch zum NaNWert "Keine Zahl". Number.isNaN()erkennen kann NaN.

Der +Bediener kann hinzufügen oder verketten.

1 + 1 //2 "1" + "1" //"11" 1 + "1" //"11"

String

Eine Zeichenfolge speichert eine Reihe von Unicode-Zeichen. Der Text kann in doppelten ""oder einfachen Anführungszeichen stehen ''.

Strings erben Methoden von String.prototype. Sie haben Methoden wie: substring(), indexOf()und concat().

"text".substring(1,3) //"ex" "text".indexOf('x') //2 "text".concat(" end") //"text end"

Zeichenfolgen sind wie alle Grundelemente unveränderlich. Ändert beispielsweise concat()nicht die vorhandene Zeichenfolge, sondern erstellt eine neue.

Boolescher Wert

Ein Boolescher Wert hat zwei Werte: trueund false.

Die Sprache hat wahrheitsgemäße und falsche Werte.

false, null, undefined, ''(Leere Zeichenkette), 0 und NaNsind falsy. Alle anderen Werte, einschließlich aller Objekte, sind wahr.

Der Wahrheitswert wird ausgewertet, truewenn er in einem booleschen Kontext ausgeführt wird. Der Falschwert wird mit bewertet false. Schauen Sie sich das nächste Beispiel an, in dem der falseZweig angezeigt wird .

let text = ''; if(text) { console.log("This is true"); } else { console.log("This is false"); }

Der Gleichheitsoperator ist ===. Der ungleiche Operator ist !==.

Variablen

Variablen können mit definiert werden var, letund const.

vardeklariert und initialisiert optional eine Variable. Mit deklarierte Variablen varhaben einen Funktionsumfang. Sie werden wie oben in der Funktion deklariert behandelt. Dies wird als variables Heben bezeichnet.

Die letDeklaration hat einen Blockumfang.

Der Wert einer Variablen, die nicht initialisiert wird, ist undefined.

Eine mit deklarierte Variable constkann nicht neu zugewiesen werden. Sein Wert kann jedoch immer noch veränderlich sein. constfriert die Variable ein, Object.freeze()friert das Objekt ein. Die constDeklaration hat einen Blockumfang.

Objekte

Ein Objekt ist eine dynamische Sammlung von Eigenschaften.

Der Eigenschaftsschlüssel ist eine eindeutige Zeichenfolge. Wenn eine Nicht-Zeichenfolge als Eigenschaftsschlüssel verwendet wird, wird sie in eine Zeichenfolge konvertiert. Der Eigenschaftswert kann ein Grundelement, ein Objekt oder eine Funktion sein.

Der einfachste Weg, ein Objekt zu erstellen, besteht darin, ein Objektliteral zu verwenden:

let obj = { message : "A message", doSomething : function() {} }

Es gibt zwei Möglichkeiten, auf Eigenschaften zuzugreifen: Punktnotation und Klammernotation. Wir können die Eigenschaften eines Objekts jederzeit lesen, hinzufügen, bearbeiten und entfernen.

  • get : object.name,object[expression]
  • einstellen: object.name = value,object[expression] = value
  • löschen : delete object.name,delete object[expression]
let obj = {}; //create empty object obj.message = "A message"; //add property obj.message = "A new message"; //edit property delete obj.message; //delete property

Objekte können als Karten verwendet werden. Eine einfache Karte kann erstellt werden mit Object.create(null):

let french = Object.create(null); french["yes"] = "oui"; french["no"] = "non"; french["yes"];//"oui"

Alle Objekteigenschaften sind öffentlich. Object.keys()kann verwendet werden, um alle Eigenschaften zu durchlaufen.

function logProperty(name){ console.log(name); //property name console.log(obj[name]); //property value } Object.keys(obj).forEach(logProperty);

Object.assign()kopiert alle Eigenschaften von einem Objekt in ein anderes. Ein Objekt kann geklont werden, indem alle seine Eigenschaften in ein leeres Objekt kopiert werden:

let book = { title: "The good parts" }; let clone = Object.assign({}, book);

Ein unveränderliches Objekt ist ein Objekt, das nach seiner Erstellung nicht mehr geändert werden kann. Wenn Sie das Objekt unveränderlich machen möchten, verwenden Sie Object.freeze().

Primitive vs Objekte

Primitive (außer nullund undefined) werden wie Objekte behandelt, in dem Sinne, dass sie Methoden haben, aber keine Objekte sind.

Zahlen, Zeichenfolgen und Boolesche Werte haben objektäquivalente Wrapper. Dies sind die Number, Stringund BooleanFunktionen.

In order to allow access to properties on primitives, JavaScript creates an wrapper object and then destroys it. The process of creating and destroying wrapper objects is optimized by the JavaScript engine.

Primitives are immutable, and objects are mutable.

Array

Arrays are indexed collections of values. Each value is an element. Elements are ordered and accessed by their index number.

JavaScript has array-like objects. Arrays are implemented using objects. Indexes are converted to strings and used as names for retrieving values.

A simple array like let arr = ['A', 'B', 'C'] is emulated using an object like the one below:

{ '0': 'A', '1': 'B', '2': 'C' }

Note that arr[1] gives the same value as arr['1'] : arr[1] === arr['1'] .

Removing values from the array with delete will leave holes. splice() can be used to avoid the problem, but it can be slow.

let arr = ['A', 'B', 'C']; delete arr[1]; console.log(arr); // ['A', empty, 'C'] console.log(arr.length); // 3

JavaScript’s arrays don’t throw “index out of range” exceptions. If the index is not available, it will return undefined.

Stack and queue can easily be implemented using the array methods:

let stack = []; stack.push(1); // [1] stack.push(2); // [1, 2] let last = stack.pop(); // [1] console.log(last); // 2 let queue = []; queue.push(1); // [1] queue.push(2); // [1, 2] let first = queue.shift();//[2] console.log(first); // 1

Functions

Functions are independent units of behavior.

Functions are objects. Functions can be assigned to variables, stored in objects or arrays, passed as an argument to other functions, and returned from functions.

There are three ways to define a function:

  • Function Declaration (aka Function Statement)
  • Function Expression (aka Function Literal)
  • Arrow Function

The Function Declaration

  • function is the first keyword on the line
  • it must have a name
  • it can be used before definition. Function declarations are moved, or “hoisted”, to the top of their scope.
function doSomething(){}

The Function Expression

  • function is not the first keyword on the line
  • the name is optional. There can be an anonymous function expression or a named function expression.
  • it needs to be defined, then it can execute
  • it can auto-execute after definition (called “IIFE” Immediately Invoked Function Expression)
let doSomething = function() {}

Arrow Function

The arrow function is a sugar syntax for creating an anonymous functionexpression.

let doSomething = () => {};

Arrow functions don’t have their own this and arguments.

Function invocation

A function, defined with the function keyword, can be invoked in different ways:

  • Function form
doSomething(arguments)
  • Method form
theObject.doSomething(arguments) theObject["doSomething"](arguments)
  • Constructor form
new Constructor(arguments)
  • Apply form
 doSomething.apply(theObject, [arguments]) doSomething.call(theObject, arguments)

Functions can be invoked with more or fewer arguments than declared in the definition. The extra arguments will be ignored, and the missing parameters will be set to undefined.

Functions (except arrow functions) have two pseudo-parameters: this and arguments.

this

Methods are functions that are stored in objects. Functions are independent. In order for a function to know on which object to work onthis is used. this represents the function’s context.

There is no point to use this when a function is invoked with the function form: doSomething(). In this case this is undefined or is the window object, depending if the strict mode is enabled or not.

When a function is invoked with the method form theObject.doSomething(),this represents the object.

When a function is used as a constructor new Constructor(), thisrepresents the newly created object.

The value of this can be set with apply() or call():doSomething.apply(theObject). In this case this is the object sent as the first parameter to the method.

The value of this depends on how the function was invoked, not where the function was defined. This is of course a source of confusion.

arguments

The arguments pseudo-parameter gives all the arguments used at invocation. It’s an array-like object, but not an array. It lacks the array methods.

function log(message){ console.log(message); } function logAll(){ let args = Array.prototype.slice.call(arguments); return args.forEach(log); } logAll("msg1", "msg2", "msg3");

An alternative is the new rest parameters syntax. This time args is an array object.

function logAll(...args){ return args.forEach(log); }

return

A function with no return statement returns undefined. Pay attention to the automatic semi-colon insertion when using return. The following function will not return an empty object, but rather an undefined one.

function getObject(){ return { } } getObject()

To avoid the issue, use { on the same line as return :

function getObject(){ return { } }

Dynamic Typing

JavaScript has dynamic typing. Values have types, variables do not. Types can change at run time.

function log(value){ console.log(value); } log(1); log("text"); log({message : "text"});

The typeof() operator can check the type of a variable.

let n = 1; typeof(n); //number let s = "text"; typeof(s); //string let fn = function() {}; typeof(fn); //function

A Single Thread

The main JavaScript runtime is single threaded. Two functions can’t run at the same time. The runtime contains an Event Queue which stores a list of messages to be processed. There are no race conditions, no deadlocks.However, the code in the Event Queue needs to run fast. Otherwise the browser will become unresponsive and will ask to kill the task.

Exceptions

JavaScript has an exception handling mechanism. It works like you may expect, by wrapping the code using the try/catch statement. The statement has a single catch block that handles all exceptions.

It’s good to know that JavaScript sometimes has a preference for silent errors. The next code will not throw an exception when I try to modify a frozen object:

let obj = Object.freeze({}); obj.message = "text";

Strict mode eliminates some JavaScript silent errors. "use strict"; enables strict mode.

Prototype Patterns

Object.create(), constructor function, and class build objects over the prototype system.

Consider the next example:

let servicePrototype = { doSomething : function() {} } let service = Object.create(servicePrototype); console.log(service.__proto__ === servicePrototype); //true

Object.create() builds a new object service which has theservicePrototype object as its prototype. This means that doSomething() is available on the service object. It also means that the __proto__ property of service points to the servicePrototype object.

Let’s now build a similar object using class.

class Service { doSomething(){} } let service = new Service(); console.log(service.__proto__ === Service.prototype);

All methods defined in the Service class will be added to theService.prototype object. Instances of the Service class will have the same prototype (Service.prototype) object. All instances will delegate method calls to the Service.prototype object. Methods are defined once onService.prototype and then inherited by all instances.

Prototype chain

Objects inherit from other objects. Each object has a prototype and inherits their properties from it. The prototype is available through the “hidden” property __proto__ .

When you request a property which the object does not contain, JavaScript will look down the prototype chain until it either finds the requested property, or until it reaches the end of the chain.

Functional Patterns

JavaScript has first class functions and closures. These are concepts that open the way for Functional Programming in JavaScript. As a result, higher order functions are possible.

filter(), map(), reduce() are the basic toolbox for working with arrays in a function style.

filter()selects values from a list based on a predicate function that decides what values should be kept.

map() transforms a list of values to another list of values using a mapping function.

let numbers = [1,2,3,4,5,6]; function isEven(number){ return number % 2 === 0; } function doubleNumber(x){ return x*2; } let evenNumbers = numbers.filter(isEven); //2 4 6 let doubleNumbers = numbers.map(doubleNumber); //2 4 6 8 10 12

reduce()reduces a list of values to one value.

function addNumber(total, value){ return total + value; } function sum(...args){ return args.reduce(addNumber, 0); } sum(1,2,3); //6

Closure is an inner function that has access to the parent function’s variables, even after the parent function has executed. Look at the next example:

function createCount(){ let state = 0; return function count(){ state += 1; return state; } } let count = createCount(); console.log(count()); //1 console.log(count()); //2

count() is a nested function. count() accesses the variable state from its parent. It survives the invocation of the parent function createCount().count() is a closure.

A higher order function is a function that takes another function as an input, returns a function, or does both.

filter(), map(), reduce() are higher-order functions.

A pure function is a function that returns a value based only of its input. Pure functions don’t use variables from the outer functions. Pure functions cause no mutations.

In the previous examples isEven(), doubleNumber(), addNumber() and sum()are pure functions.

Conclusion

The power of JavaScript lies in its simplicity.

Knowing the JavaScript fundamentals makes us better at understanding and using the language.

Learn functional React, in a project-based way, with Functional Architecture with React and Redux.

Discover Functional JavaScript was named one of thebest new Functional Programming books by BookAuthority!

For more on applying functional programming techniques in React take a look atFunctional React.

Follow on Twitter