diff options
author | Peter Bengtsson <mail@peterbe.com> | 2021-07-15 12:58:54 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-15 12:58:54 -0400 |
commit | 9ace67d06f2369e3c770e3a11e06e1c8cc9f66fd (patch) | |
tree | 6fd33b1d14bd8f53a73291e4afa6f9d6400f1964 /files/de/learn/javascript | |
parent | fe0831846de29cce74db723e625c90b1ef966d9d (diff) | |
download | translated-content-9ace67d06f2369e3c770e3a11e06e1c8cc9f66fd.tar.gz translated-content-9ace67d06f2369e3c770e3a11e06e1c8cc9f66fd.tar.bz2 translated-content-9ace67d06f2369e3c770e3a11e06e1c8cc9f66fd.zip |
delete pages that were never translated from en-US (de, part 1) (#1548)
Diffstat (limited to 'files/de/learn/javascript')
3 files changed, 0 insertions, 1414 deletions
diff --git a/files/de/learn/javascript/building_blocks/events/index.html b/files/de/learn/javascript/building_blocks/events/index.html deleted file mode 100644 index 88c8c66afd..0000000000 --- a/files/de/learn/javascript/building_blocks/events/index.html +++ /dev/null @@ -1,588 +0,0 @@ ---- -title: Einleitung der Ereignissen -slug: Learn/JavaScript/Building_blocks/Events -translation_of: Learn/JavaScript/Building_blocks/Events -original_slug: Learn/JavaScript/Bausteine/Ereignisse ---- -<div>{{LearnSidebar}}</div> - -<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</div> - -<p class="summary">Events oder auch Ereignisse sind Vorfälle die im System ausgelöst werden können. Auf diese Events wird vom System aufmerksam gemacht und es ust möglich, in irgendeiner Art und Weise darauf zu reagieren.<br> - Ein Beispiel: Ein Benutzer klickt einen Knopf auf der Website, woraufhin eine Box mit Infromationen eingeblendet wird.<br> - In diesem Artikel besprechen wir einige wichtige Konzepte rund um die Events und deren Funktionsweise im Browser. Wir werden hierbei nicht auf jedes Detail eingehen und nur das bis zum jetzigen Wissensstandpunkt nötigste abdecken.</p> - -<table class="learn-box standard-table"> - <tbody> - <tr> - <th scope="row">Prerequisites:</th> - <td>Basic computer literacy, a basic understanding of HTML and CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td> - </tr> - <tr> - <th scope="row">Objective:</th> - <td>To understand the fundamental theory of events, how they work in browsers, and how events may differ in different programming environments.</td> - </tr> - </tbody> -</table> - -<h2 id="A_series_of_fortunate_events">A series of fortunate events</h2> - -<p>As mentioned above, <strong>events</strong> are actions or occurrences that happen in the system you are programming — the system produces (or "fires") a signal of some kind when an event occurs, and also provides a mechanism by which some kind of action can be automatically taken (that is, some code running) when the event occurs. For example in an airport when the runway is clear for a plane to take off, a signal is communicated to the pilot, and as a result, they commence piloting the plane.</p> - -<p><img alt="" src="https://mdn.mozillademos.org/files/14077/MDN-mozilla-events-runway.png" style="display: block; margin: 0px auto;"></p> - -<p>In the case of the Web, events are fired inside the browser window, and tend to be attached to a specific item that resides in it — this might be a single element, set of elements, the HTML document loaded in the current tab, or the entire browser window. There are a lot of different types of events that can occur, for example:</p> - -<ul> - <li>The user clicking the mouse over a certain element or hovering the cursor over a certain element.</li> - <li>The user pressing a key on the keyboard.</li> - <li>The user resizing or closing the browser window.</li> - <li>A web page finishing loading.</li> - <li>A form being submitted.</li> - <li>A video being played, or paused, or finishing play.</li> - <li>An error occurring.</li> -</ul> - -<p>You can gather from this (and from glancing at the MDN <a href="/en-US/docs/Web/Events">Event reference</a>) that there are <strong>a lot</strong> of events that can be responded to.</p> - -<p>Each available event has an <strong>event handler</strong>, which is a block of code (usually a JavaScript function that you as a programmer create) that will be run when the event fires. When such a block of code is defined to be run in response to an event firing, we say we are <strong>registering an event handler</strong>. Note that event handlers are sometimes called <strong>event listeners</strong> — they are pretty much interchangeable for our purposes, although strictly speaking, they work together. The listener listens out for the event happening, and the handler is the code that is run in response to it happening.</p> - -<div class="note"> -<p><strong>Note</strong>: Web events are not part of the core JavaScript language — they are defined as part of the APIs built into the browser.</p> -</div> - -<h3 id="A_simple_example">A simple example</h3> - -<p>Let's look at a simple example to explain what we mean here. You've already seen events and event handlers used in many of the examples in this course already, but let's recap just to cement our knowledge. In the following example, we have a single {{htmlelement("button")}}, which when pressed, makes the background change to a random color:</p> - -<pre class="brush: html"><button>Change color</button></pre> - -<div class="hidden"> -<pre class="brush: css">button { margin: 10px };</pre> -</div> - -<p>The JavaScript looks like so:</p> - -<pre class="brush: js">const btn = document.querySelector('button'); - -function random(number) { - return Math.floor(Math.random() * (number+1)); -} - -btn.onclick = function() { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -}</pre> - -<p>In this code, we store a reference to the button inside a constant called <code>btn</code>, using the {{domxref("Document.querySelector()")}} function. We also define a function that returns a random number. The third part of the code is the event handler. The <code>btn</code> constant points to a <code><a href="/en-US/docs/Web/HTML/Element/button"><button></a></code> element, and this type of object has a number of events that can fire on it, and therefore, event handlers available. We are listening for the <code><a href="/en-US/docs/Web/API/Element/click_event">click</a></code> event firing, by setting the <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onclick">onclick</a></code> event handler property to equal an anonymous function containing code that generates a random RGB color and sets the <code><a href="/en-US/docs/Web/HTML/Element/body"><body></a></code> <code><a href="/en-US/docs/Web/CSS/background-color">background-color</a></code> equal to it.</p> - -<p>This code is run whenever the click event fires on the <code><button></code> element, that is, whenever a user clicks on it.</p> - -<p>The example output is as follows:</p> - -<p>{{ EmbedLiveSample('A_simple_example', '100%', 200, "", "", "hide-codepen-jsfiddle") }}</p> - -<h3 id="Its_not_just_web_pages">It's not just web pages</h3> - -<p>Another thing worth mentioning at this point is that events are not unique to JavaScript — most programming languages have some kind of event model, and the way the model works often differs from JavaScript's way. In fact, the event model in JavaScript for web pages differs from the event model for JavaScript as it is used in other environments.</p> - -<p>For example, <a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Node.js</a> is a very popular JavaScript runtime that enables developers to use JavaScript to build network and server-side applications. The <a href="https://nodejs.org/docs/latest-v12.x/api/events.html">Node.js event model</a> relies on listeners to listen for events and emitters to emit events periodically — it doesn't sound that different, but the code is quite different, making use of functions like <code>on()</code> to register an event listener, and <code>once()</code> to register an event listener that unregisters after it has run once. The <a href="https://nodejs.org/docs/latest-v12.x/api/http.html#http_event_connect">HTTP connect event docs</a> provide a good example of use.</p> - -<p>As another example, you can also use JavaScript to build cross-browser add-ons — browser functionality enhancements — using a technology called <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a>. The event model is similar to the web events model, but a bit different — event listeners properties are camel-cased (such as <code>onMessage</code> rather than <code>onmessage</code>), and need to be combined with the <code>addListener</code> function. See the <a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage#Examples"><code>runtime.onMessage</code> page</a> for an example.</p> - -<p>You don't need to understand anything about other such environments at this stage in your learning; we just wanted to make it clear that events can differ in different programming environments.</p> - -<h2 id="Ways_of_using_web_events">Ways of using web events</h2> - -<p>There are a number of ways in which you can add event listener code to web pages so that it will be run when the associated event fires. In this section, we review the various mechanisms and discuss which ones you should use.</p> - -<h3 id="Event_handler_properties">Event handler properties</h3> - -<p>These are the properties that exist to contain event handler code that we have seen most frequently during the course. Returning to the above example:</p> - -<pre class="brush: js">const btn = document.querySelector('button'); - -btn.onclick = function() { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -}</pre> - -<p>The <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onclick">onclick</a></code> property is the event handler property being used in this situation. It is essentially a property like any other available on the button (e.g. <code><a href="/en-US/docs/Web/API/Node/textContent">btn.textContent</a></code>, or <code><a href="/en-US/docs/Web/API/HTMLElement/style">btn.style</a></code>), but it is a special type — when you set it to be equal to some code, that code is run when the event fires on the button.</p> - -<p>You could also set the handler property to be equal to a named function name (like we saw in <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a>). The following would work just the same:</p> - -<pre class="brush: js">const btn = document.querySelector('button'); - -function bgChange() { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -} - -btn.onclick = bgChange;</pre> - -<p>There are many different event handler properties available. Let's do an experiment.</p> - -<p>First of all, make a local copy of <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerproperty.html">random-color-eventhandlerproperty.html</a>, and open it in your browser. It's just a copy of the simple random color example we've been playing with already in this article. Now try changing <code>btn.onclick</code> to the following different values in turn, and observing the results in the example:</p> - -<ul> - <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onfocus">btn.onfocus</a></code> and <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onblur">btn.onblur</a></code> — The color changes when the button is focused and unfocused; try pressing tab to focus on the button and press tab again to focus away from the button. These are often used to display information about how to fill in form fields when they are focused, or display an error message if a form field has just been filled in with an incorrect value.</li> - <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/ondblclick">btn.ondblclick</a></code> — The color changes only when the button is double-clicked.</li> - <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeypress">window.onkeypress</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeydown">window.onkeydown</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeyup">window.onkeyup</a></code> — The color changes when a key is pressed on the keyboard. The <code>keypress</code> event refers to a general press (button down and then up), while <code>keydown</code> and <code>keyup</code> refer to just the key down and key up parts of the keystroke, respectively. Note that it doesn't work if you try to register this event handler on the button itself — we've had to register it on the <a href="/en-US/docs/Web/API/Window">window</a> object, which represents the entire browser window.</li> - <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseover">btn.onmouseover</a></code> and <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseout">btn.onmouseout</a></code> — The color changes when the mouse pointer is moved so it begins hovering over the button, or when pointer stops hovering over the button and moves off of it, respectively.</li> -</ul> - -<p>Some events are very general and available nearly anywhere (for example an <code>onclick</code> handler can be registered on nearly any element), whereas some are more specific and only useful in certain situations (for example it makes sense to use <a href="/en-US/docs/Web/API/GlobalEventHandlers/GlobalEventHandlers.onplay">onplay</a> only on specific elements, such as {{htmlelement("video")}}).</p> - -<h3 id="Inline_event_handlers_—_dont_use_these">Inline event handlers — don't use these</h3> - -<p>You might also see a pattern like this in your code:</p> - -<pre class="brush: html"><button onclick="bgChange()">Press me</button> -</pre> - -<pre class="brush: js">function bgChange() { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -}</pre> - -<div class="note"> -<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerattributes.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventhandlerattributes.html">see it running live</a>).</p> -</div> - -<p>The earliest method of registering event handlers found on the Web involved <strong>event handler HTML attributes</strong> (or <strong>inline event handlers</strong>) like the one shown above — the attribute value is literally the JavaScript code you want to run when the event occurs. The above example invokes a function defined inside a {{htmlelement("script")}} element on the same page, but you could also insert JavaScript directly inside the attribute, for example:</p> - -<pre class="brush: html"><button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button></pre> - -<p>You can find HTML attribute equivalents for many of the event handler properties; however, you shouldn't use these — they are considered bad practice. It might seem easy to use an event handler attribute if you are just doing something really quick, but they very quickly become unmanageable and inefficient.</p> - -<p>For a start, it is not a good idea to mix up your HTML and your JavaScript, as it becomes hard to parse — keeping your JavaScript all in one place is better; if it is in a separate file you can apply it to multiple HTML documents.</p> - -<p>Even in a single file, inline event handlers are not a good idea. One button is OK, but what if you had 100 buttons? You'd have to add 100 attributes to the file; it would very quickly turn into a maintenance nightmare. With JavaScript, you could easily add an event handler function to all the buttons on the page no matter how many there were, using something like this:</p> - -<pre class="brush: js">const buttons = document.querySelectorAll('button'); - -for (let i = 0; i < buttons.length; i++) { - buttons[i].onclick = bgChange; -}</pre> - -<p class="brush: js">Note that another option here would be to use the <code><a href="/en-US/docs/Web/API/NodeList/forEach">forEach()</a></code> built-in method available on <code><a href="/en-US/docs/Web/API/NodeList">NodeList</a></code> objects:</p> - -<pre class="brush: js">buttons.forEach(function(button) { - button.onclick = bgChange; -});</pre> - -<div class="note"> -<p><strong>Note</strong>: Separating your programming logic from your content also makes your site more friendly to search engines.</p> -</div> - -<h3 id="addEventListener_and_removeEventListener">addEventListener() and removeEventListener()</h3> - -<p>The newest type of event mechanism is defined in the <a href="https://www.w3.org/TR/DOM-Level-2-Events/">Document Object Model (DOM) Level 2 Events</a> Specification, which provides browsers with a new function — <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>. This functions in a similar way to the event handler properties, but the syntax is obviously different. We could rewrite our random color example to look like this:</p> - -<pre class="brush: js">const btn = document.querySelector('button'); - -function bgChange() { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -} - -btn.addEventListener('click', bgChange);</pre> - -<div class="note"> -<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-addeventlistener.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-addeventlistener.html">see it running live</a>).</p> -</div> - -<p>Inside the <code>addEventListener()</code> function, we specify two parameters — the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note that it is perfectly appropriate to put all the code inside the <code>addEventListener()</code> function, in an anonymous function, like this:</p> - -<pre class="brush: js">btn.addEventListener('click', function() { - var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - document.body.style.backgroundColor = rndCol; -});</pre> - -<p>This mechanism has some advantages over the older mechanisms discussed earlier. For a start, there is a counterpart function, <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code>, which removes a previously added listener. For example, this would remove the listener set in the first code block in this section:</p> - -<pre class="brush: js">btn.removeEventListener('click', bgChange);</pre> - -<p>This isn't significant for simple, small programs, but for larger, more complex programs it can improve efficiency to clean up old unused event handlers. Plus, for example, this allows you to have the same button performing different actions in different circumstances — all you have to do is add or remove event handlers as appropriate.</p> - -<p>Second, you can also register multiple handlers for the same listener. The following two handlers wouldn't both be applied:</p> - -<pre class="brush: js">myElement.onclick = functionA; -myElement.onclick = functionB;</pre> - -<p>The second line overwrites the value of <code>onclick</code> set by the first line. This would work, however:</p> - -<pre class="brush: js">myElement.addEventListener('click', functionA); -myElement.addEventListener('click', functionB);</pre> - -<p>Both functions would now run when the element is clicked.</p> - -<p>In addition, there are a number of other powerful features and options available with this event mechanism. These are a little out of scope for this article, but if you want to read up on them, have a look at the <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code> and <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code> reference pages.</p> - -<h3 id="What_mechanism_should_I_use">What mechanism should I use?</h3> - -<p>Of the three mechanisms, you definitely shouldn't use the HTML event handler attributes — these are outdated, and bad practice, as mentioned above.</p> - -<p>The other two are relatively interchangeable, at least for simple uses:</p> - -<ul> - <li>Event handler properties have less power and options, but better cross-browser compatibility (being supported as far back as Internet Explorer 8). You should probably start with these as you are learning.</li> - <li>DOM Level 2 Events (<code>addEventListener()</code>, etc.) are more powerful, but can also become more complex and are less well supported (supported as far back as Internet Explorer 9). You should also experiment with these, and aim to use them where possible.</li> -</ul> - -<p>The main advantages of the third mechanism are that you can remove event handler code if needed, using <code>removeEventListener()</code>, and you can add multiple listeners of the same type to elements if required. For example, you can call <code>addEventListener('click', function() { ... })</code> on an element multiple times, with different functions specified in the second argument. This is impossible with event handler properties because any subsequent attempts to set a property will overwrite earlier ones, e.g.:</p> - -<pre class="brush: js">element.onclick = function1; -element.onclick = function2; -etc.</pre> - -<div class="note"> -<p><strong>Note</strong>: If you are called upon to support browsers older than Internet Explorer 8 in your work, you may run into difficulties, as such ancient browsers use different event models from newer browsers. But never fear, most JavaScript libraries (for example <code>jQuery</code>) have built-in functions that abstract away cross-browser differences. Don't worry about this too much at this stage in your learning journey.</p> -</div> - -<h2 id="Other_event_concepts">Other event concepts</h2> - -<p>In this section, we briefly cover some advanced concepts that are relevant to events. It is not important to understand these concepts fully at this point, but they might serve to explain some code patterns you'll likely come across from time to time.</p> - -<h3 id="Event_objects">Event objects</h3> - -<p>Sometimes inside an event handler function, you might see a parameter specified with a name such as <code>event</code>, <code>evt</code>, or simply <code>e</code>. This is called the <strong>event object</strong>, and it is automatically passed to event handlers to provide extra features and information. For example, let's rewrite our random color example again slightly:</p> - -<pre class="brush: js">function bgChange(e) { - const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - e.target.style.backgroundColor = rndCol; - console.log(e); -} - -btn.addEventListener('click', bgChange);</pre> - -<div class="note"> -<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventobject.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventobject.html">see it running live</a>).</p> -</div> - -<p>Here you can see that we are including an event object, <strong>e</strong>, in the function, and in the function setting a background color style on <code>e.target</code> — which is the button itself. The <code>target</code> property of the event object is always a reference to the element that the event has just occurred upon. So in this example, we are setting a random background color on the button, not the page.</p> - -<div class="note"> -<p><strong>Note</strong>: You can use any name you like for the event object — you just need to choose a name that you can then use to reference it inside the event handler function. <code>e</code>/<code>evt</code>/<code>event</code> are most commonly used by developers because they are short and easy to remember. It's always good to be consistent — with yourself, and with others if possible.</p> -</div> - -<p><code>e.target</code> is incredibly useful when you want to set the same event handler on multiple elements and do something to all of them when an event occurs on them. You might, for example, have a set of 16 tiles that disappear when they are clicked on. It is useful to always be able to just set the thing to disappear as <code>e.target</code>, rather than having to select it in some more difficult way. In the following example (see <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/useful-eventtarget.html">useful-eventtarget.html</a> for the full source code; also see it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/useful-eventtarget.html">running live</a> here), we create 16 {{htmlelement("div")}} elements using JavaScript. We then select all of them using {{domxref("document.querySelectorAll()")}}, then loop through each one, adding an <code>onclick</code> handler to each that makes it so that a random color is applied to each one when clicked:</p> - -<pre class="brush: js">const divs = document.querySelectorAll('div'); - -for (let i = 0; i < divs.length; i++) { - divs[i].onclick = function(e) { - e.target.style.backgroundColor = bgChange(); - } -}</pre> - -<p>The output is as follows (try clicking around on it — have fun):</p> - -<div class="hidden"> -<h6 id="Hidden_example">Hidden example</h6> - -<pre class="brush: html"><!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Useful event target example</title> - <style> - div { - height: 100px; - width: 25%; - float: left; - } - </style> - </head> - <body> - <script> - for (let i = 1; i <= 16; i++) { - const myDiv = document.createElement('div'); - myDiv.style.backgroundColor = "red"; - document.body.appendChild(myDiv); - } - - function random(number) { - return Math.floor(Math.random()*number); - } - - function bgChange() { - var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; - return rndCol; - } - - const divs = document.querySelectorAll('div'); - - for (let i = 0; i < divs.length; i++) { - divs[i].onclick = function(e) { - e.target.style.backgroundColor = bgChange(); - } - } - </script> - </body> -</html></pre> -</div> - -<p>{{ EmbedLiveSample('Hidden_example', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p> - -<p>Most event handlers you'll encounter just have a standard set of properties and functions (methods) available on the event object; see the {{domxref("Event")}} object reference for a full list. Some more advanced handlers, however, add specialist properties containing extra data that they need to function. The <a href="/en-US/docs/Web/API/MediaRecorder_API">Media Recorder API</a>, for example, has a <code>dataavailable</code> event, which fires when some audio or video has been recorded and is available for doing something with (for example saving it, or playing it back). The corresponding <a href="/en-US/docs/Web/API/MediaRecorder/ondataavailable">ondataavailable</a> handler's event object has a <code>data</code> property available containing the recorded audio or video data to allow you to access it and do something with it.</p> - -<h3 id="Preventing_default_behavior">Preventing default behavior</h3> - -<p>Sometimes, you'll come across a situation where you want to prevent an event from doing what it does by default. The most common example is that of a web form, for example, a custom registration form. When you fill in the details and press the submit button, the natural behavior is for the data to be submitted to a specified page on the server for processing, and the browser to be redirected to a "success message" page of some kind (or the same page, if another is not specified.)</p> - -<p>The trouble comes when the user has not submitted the data correctly — as a developer, you want to prevent the submission to the server and give an error message saying what's wrong and what needs to be done to put things right. Some browsers support automatic form data validation features, but since many don't, you are advised to not rely on those and implement your own validation checks. Let's look at a simple example.</p> - -<p>First, a simple HTML form that requires you to enter your first and last name:</p> - -<pre class="brush: html"><form> - <div> - <label for="fname">First name: </label> - <input id="fname" type="text"> - </div> - <div> - <label for="lname">Last name: </label> - <input id="lname" type="text"> - </div> - <div> - <input id="submit" type="submit"> - </div> -</form> -<p></p></pre> - -<div class="hidden"> -<pre class="brush: css">div { - margin-bottom: 10px; -} -</pre> -</div> - -<p>Now some JavaScript — here we implement a very simple check inside an <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onsubmit">onsubmit</a></code> event handler (the submit event is fired on a form when it is submitted) that tests whether the text fields are empty. If they are, we call the <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> function on the event object — which stops the form submission — and then display an error message in the paragraph below our form to tell the user what's wrong:</p> - -<pre class="brush: js">const form = document.querySelector('form'); -const fname = document.getElementById('fname'); -const lname = document.getElementById('lname'); -const para = document.querySelector('p'); - -form.onsubmit = function(e) { - if (fname.value === '' || lname.value === '') { - e.preventDefault(); - para.textContent = 'You need to fill in both names!'; - } -}</pre> - -<p>Obviously, this is pretty weak form validation — it wouldn't stop the user validating the form with spaces or numbers entered into the fields, for example — but it is OK for example purposes. The output is as follows:</p> - -<p>{{ EmbedLiveSample('Preventing_default_behavior', '100%', 140, "", "", "hide-codepen-jsfiddle") }}</p> - -<div class="note"> -<p><strong>Note</strong>: for the full source code, see <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/preventdefault-validation.html">preventdefault-validation.html</a> (also see it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/preventdefault-validation.html">running live</a> here.)</p> -</div> - -<h3 id="Event_bubbling_and_capture">Event bubbling and capture</h3> - -<p>The final subject to cover here is something that you won't come across often, but it can be a real pain if you don't understand it. Event bubbling and capture are two mechanisms that describe what happens when two handlers of the same event type are activated on one element. Let's look at an example to make this easier — open up the <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box.html">show-video-box.html</a> example in a new tab (and the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">source code</a> in another tab.) It is also available live below:</p> - -<div class="hidden"> -<h6 id="Hidden_video_example">Hidden video example</h6> - -<pre class="brush: html"><!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Show video box example</title> - <style> - div { - position: absolute; - top: 50%; - transform: translate(-50%,-50%); - width: 480px; - height: 380px; - border-radius: 10px; - background-color: #eee; - background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1)); - } - - .hidden { - left: -50%; - } - - .showing { - left: 50%; - } - - div video { - display: block; - width: 400px; - margin: 40px auto; - } - - </style> - </head> - <body> - <button>Display video</button> - - <div class="hidden"> - <video> - <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.mp4" type="video/mp4"> - <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.webm" type="video/webm"> - <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> - </video> - </div> - - <script> - - const btn = document.querySelector('button'); - const videoBox = document.querySelector('div'); - const video = document.querySelector('video'); - - btn.onclick = function() { - displayVideo(); - } - - function displayVideo() { - if(videoBox.getAttribute('class') === 'hidden') { - videoBox.setAttribute('class','showing'); - } - } - - videoBox.addEventListener('click',function() { - videoBox.setAttribute('class','hidden'); - }); - - video.addEventListener('click',function() { - video.play(); - }); - - </script> - </body> -</html></pre> -</div> - -<p>{{ EmbedLiveSample('Hidden_video_example', '100%', 500, "", "", "hide-codepen-jsfiddle") }}</p> - -<p>This is a pretty simple example that shows and hides a {{htmlelement("div")}} with a {{htmlelement("video")}} element inside it:</p> - -<pre class="brush: html"><button>Display video</button> - -<div class="hidden"> - <video> - <source src="rabbit320.mp4" type="video/mp4"> - <source src="rabbit320.webm" type="video/webm"> - <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> - </video> -</div></pre> - -<p>When the {{htmlelement("button")}} is clicked, the video is displayed, by changing the class attribute on the <code><div></code> from <code>hidden</code> to <code>showing</code> (the example's CSS contains these two classes, which position the box off the screen and on the screen, respectively):</p> - -<pre class="brush: js">btn.onclick = function() { - videoBox.setAttribute('class', 'showing'); -}</pre> - -<p>We then add a couple more <code>onclick</code> event handlers — the first one to the <code><div></code> and the second one to the <code><video></code>. The idea is that when the area of the <code><div></code> outside the video is clicked, the box should be hidden again; when the video itself is clicked, the video should start to play.</p> - -<pre class="brush: js">videoBox.onclick = function() { - videoBox.setAttribute('class', 'hidden'); -}; - -video.onclick = function() { - video.play(); -};</pre> - -<p>But there's a problem — currently, when you click the video it starts to play, but it causes the <code><div></code> to also be hidden at the same time. This is because the video is inside the <code><div></code> — it is part of it — so clicking on the video actually runs <em>both</em> the above event handlers.</p> - -<h4 id="Bubbling_and_capturing_explained">Bubbling and capturing explained</h4> - -<p>When an event is fired on an element that has parent elements (in this case, the {{htmlelement("video")}} has the {{htmlelement("div")}} as a parent), modern browsers run two different phases — the <strong>capturing</strong> phase and the <strong>bubbling</strong> phase.</p> - -<p>In the <strong>capturing</strong> phase:</p> - -<ul> - <li>The browser checks to see if the element's outer-most ancestor ({{htmlelement("html")}}) has an <code>onclick</code> event handler registered on it for the capturing phase, and runs it if so.</li> - <li>Then it moves on to the next element inside <code><html></code> and does the same thing, then the next one, and so on until it reaches the element that was actually clicked on.</li> -</ul> - -<p>In the <strong>bubbling</strong> phase, the exact opposite occurs:</p> - -<ul> - <li>The browser checks to see if the element that was actually clicked on has an <code>onclick</code> event handler registered on it for the bubbling phase, and runs it if so.</li> - <li>Then it moves on to the next immediate ancestor element and does the same thing, then the next one, and so on until it reaches the <code><html></code> element.</li> -</ul> - -<p><a href="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png"><img alt="" src="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png" style="display: block; height: 452px; margin: 0px auto; width: 960px;"></a></p> - -<p>(Click on image for bigger diagram)</p> - -<p>In modern browsers, by default, all event handlers are registered for the bubbling phase. So in our current example, when you click the video, the click event bubbles from the <code><video></code> element outwards to the <code><html></code> element. Along the way:</p> - -<ul> - <li>It finds the <code>video.onclick...</code> handler and runs it, so the video first starts playing.</li> - <li>It then finds the <code>videoBox.onclick...</code> handler and runs it, so the video is hidden as well.</li> -</ul> - -<div class="blockIndicator note"> -<p><strong>Note</strong>: In cases where both types of event handlers are present, bubbling and capturing, the capturing phase will run first, followed by the bubbling phase.</p> -</div> - -<h4 id="Fixing_the_problem_with_stopPropagation">Fixing the problem with stopPropagation()</h4> - -<p>This is annoying behavior, but there is a way to fix it! The standard <code><a href="/en-US/docs/Web/API/Event">Event</a></code> object has a function available on it called <code><a href="/en-US/docs/Web/API/Event/stopPropagation">stopPropagation()</a></code> which, when invoked on a handler's event object, makes it so that first handler is run but the event doesn't bubble any further up the chain, so no more handlers will be run.</p> - -<p>We can, therefore, fix our current problem by changing the second handler function in the previous code block to this:</p> - -<pre class="brush: js">video.onclick = function(e) { - e.stopPropagation(); - video.play(); -};</pre> - -<p>You can try making a local copy of the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">show-video-box.html source code</a> and fixing it yourself, or looking at the fixed result in <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box-fixed.html">show-video-box-fixed.html</a> (also see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box-fixed.html">source code</a> here).</p> - -<div class="note"> -<p><strong>Note</strong>: Why bother with both capturing and bubbling? Well, in the bad old days when browsers were much less cross-compatible than they are now, Netscape only used event capturing, and Internet Explorer used only event bubbling. When the W3C decided to try to standardize the behavior and reach a consensus, they ended up with this system that included both, which is the one modern browsers implemented.</p> -</div> - -<div class="note"> -<p><strong>Note</strong>: As mentioned above, by default all event handlers are registered in the bubbling phase, and this makes more sense most of the time. If you really want to register an event in the capturing phase instead, you can do so by registering your handler using <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>, and setting the optional third property to <code>true</code>.</p> -</div> - -<h4 id="Event_delegation">Event delegation</h4> - -<p>Bubbling also allows us to take advantage of <strong>event delegation</strong> — this concept relies on the fact that if you want some code to run when you click on any one of a large number of child elements, you can set the event listener on their parent and have events that happen on them bubble up to their parent rather than having to set the event listener on every child individually. Remember earlier that we said bubbling involves checking the element the event is fired on for an event handler first, then moving up to the element's parent, etc.?</p> - -<p>A good example is a series of list items — if you want each one of them to pop up a message when clicked, you can set the <code>click</code> event listener on the parent <code><ul></code>, and events will bubble from the list items to the <code><ul></code>.</p> - -<p>This concept is explained further on David Walsh's blog, with multiple examples — see <a href="https://davidwalsh.name/event-delegate">How JavaScript Event Delegation Works</a>.</p> - -<h2 id="Test_your_skills!">Test your skills!</h2> - -<p>You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Test_your_skills:_Events">Test your skills: Events</a>.</p> - -<h2 id="Conclusion">Conclusion</h2> - -<p>You should now know all you need to know about web events at this early stage. As mentioned above, events are not really part of the core JavaScript — they are defined in browser Web APIs.</p> - -<p>Also, it is important to understand that the different contexts in which JavaScript is used have different event models — from Web APIs to other areas such as browser WebExtensions and Node.js (server-side JavaScript). We are not expecting you to understand all these areas now, but it certainly helps to understand the basics of events as you forge ahead with learning web development.</p> - -<p>If there is anything you didn't understand, feel free to read through the article again, or <a href="https://discourse.mozilla.org/c/mdn/learn">contact us</a> to ask for help.</p> - -<h2 id="See_also">See also</h2> - -<ul> - <li><a href="http://www.quirksmode.org/js/events_order.html">Event order</a> (discussion of capturing and bubbling) — an excellently detailed piece by Peter-Paul Koch.</li> - <li><a href="http://www.quirksmode.org/js/events_access.html">Event accessing</a> (discussion of the event object) — another excellently detailed piece by Peter-Paul Koch.</li> - <li><a href="/en-US/docs/Web/Events">Event reference</a></li> -</ul> - -<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</p> - -<h2 id="In_this_module">In this module</h2> - -<ul> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> -</ul> diff --git a/files/de/learn/javascript/first_steps/variables/index.html b/files/de/learn/javascript/first_steps/variables/index.html deleted file mode 100644 index d8906f7d02..0000000000 --- a/files/de/learn/javascript/first_steps/variables/index.html +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: Speichern der benötigten Informationen — Variablen -slug: Learn/JavaScript/First_steps/Variables -translation_of: Learn/JavaScript/First_steps/Variables ---- -<div>{{LearnSidebar}}</div> - -<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}</div> - -<p class="summary">After reading the last couple of articles you should now know what JavaScript is, what it can do for you, how you use it alongside other web technologies, and what its main features look like from a high level. In this article, we will get down to the real basics, looking at how to work with the most basic building blocks of JavaScript — Variables.</p> - -<table class="learn-box"> - <tbody> - <tr> - <th scope="row">Prerequisites:</th> - <td>Basic computer literacy, a basic understanding of HTML and CSS, an understanding of what JavaScript is.</td> - </tr> - <tr> - <th scope="row">Objective:</th> - <td>To gain familiarity with the basics of JavaScript variables.</td> - </tr> - </tbody> -</table> - -<h2 id="Tools_you_need">Tools you need</h2> - -<p>Throughout this article, you'll be asked to type in lines of code to test your understanding of the content. If you are using a desktop browser, the best place to type your sample code is your browser's JavaScript console (see <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">What are browser developer tools</a> for more information on how to access this tool).</p> - -<p>However, we have also provided a simple JavaScript console embedded in the page below for you to enter this code into, in case you are not using a browser with a JavaScript console easily available, or find an in-page console more comfortable.</p> - -<h2 id="Was_ist_eine_Variable">Was ist eine Variable?</h2> - -<p>Eine Variable ist ein Behälter für einen Wert, wie z.B. eine Zahl, welche wir vielleicht für eine Summe benötigen, oder eine Zeichenkette die wir für einen Teil eines Satzes brauchen. Eine Besonderheit von Variablen ist, dass ihr Wert verändert werden kann. Hier ein Beispiel:</p> - -<pre class="brush: html"><button>Press me</button></pre> - -<pre class="brush: js">var button = document.querySelector('button'); - -button.onclick = function() { - var name = prompt('Wie heißt du?'); - alert('Hallo ' + name + ', schön dich zu sehen!'); -}</pre> - -<p>{{ EmbedLiveSample('What_is_a_variable', '100%', 50, "", "", "hide-codepen-jsfiddle") }}</p> - -<p>In diesem Beispiel werden beim Drücken des Buttons einige Zeilen Code ausgeführt. Die erste Zeile zeigt eine Box an, welche den Leser nach seinem Namen fragt und den Wert anschließend in einer Variable abspeichert. Die zweite Zeile zeigt eine Willkommensnachricht, die den Namen enthält, welcher dem Wert der Variable entnommen wird.</p> - -<p>Um zu verstehen, warum das so nützlich ist, überlegen wir mal, wie wir das Beispiel ohne eine Variable schreiben würden. Es würde etwa so aussehen:</p> - -<pre class="example-bad">var name = prompt('Wie heißt du?'); - -if (name === 'Adam') { - alert('Hallo Adam, schön dich zu sehen!'); -} else if (name === 'Alan') { - alert('Hallo Alan, schön dich zu sehen!'); -} else if (name === 'Bella') { - alert('Hallo Bella, schön dich zu sehen!'); -} else if (name === 'Bianca') { - alert('Hallo Bianca, schön dich zu sehen!'); -} else if (name === 'Chris') { - alert('Hallo Chris, schön dich zu sehen!'); -} - -// ... und so weiter ...</pre> - -<p>You may not fully understand the syntax we are using (yet!), but you should be able to get the idea — if we didn't have variables available, we'd have to implement a giant code block that checked what the entered name was, and then display the appropriate message for that name. This is obviously really inefficient (the code is a lot bigger, even for only five choices), and it just wouldn't work — you couldn't possibly store all possible choices.</p> - -<p>Variables just make sense, and as you learn more about JavaScript they will start to become second nature.</p> - -<p>Another special thing about variables is that they can contain just about anything — not just strings and numbers. Variables can also contain complex data and even entire functions to do amazing things. You'll learn more about this as you go along.</p> - -<p><u><strong>Note that we say variables contain values. This is an important distinction to make. Variables aren't the values themselves; they are containers for values. You can think of them being like little cardboard boxes that you can store things in.</strong></u></p> - -<p><img alt="" src="https://mdn.mozillademos.org/files/13506/boxes.png" style="display: block; height: 436px; margin: 0px auto; width: 1052px;"></p> - -<h2 id="Eine_Variable_deklarieren">Eine Variable deklarieren</h2> - -<p>To use a variable you've first got to create it — more accurately, we call this declaring the variable. To do this, we type the keyword var followed by the name you want to call your variable:</p> - -<pre class="brush: js">var myName; -var myAge;</pre> - -<p>Here we're creating two variables called <code>myName</code> and <code>myAge</code>. Try typing these lines in now in your web browser's console, or in the below console (You can <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">open this console</a> in a separate tab or window if you'd prefer that). After that, try creating a variable (or two) with your own name choices.</p> - -<div class="hidden"> -<h6 id="Hidden_code">Hidden code</h6> - -<pre class="brush: html"><!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>JavaScript console</title> - <style> - * { - box-sizing: border-box; - } - - html { - background-color: #0C323D; - color: #809089; - font-family: monospace; - } - - body { - max-width: 700px; - } - - p { - margin: 0; - width: 1%; - padding: 0 1%; - font-size: 16px; - line-height: 1.5; - float: left; - } - - .input p { - margin-right: 1%; - } - - .output p { - width: 100%; - } - - .input input { - width: 96%; - float: left; - border: none; - font-size: 16px; - line-height: 1.5; - font-family: monospace; - padding: 0; - background: #0C323D; - color: #809089; - } - - div { - clear: both; - } - - </style> - </head> - <body> - - - </body> - - <script> - var geval = eval; - function createInput() { - var inputDiv = document.createElement('div'); - var inputPara = document.createElement('p'); - var inputForm = document.createElement('input'); - - inputDiv.setAttribute('class','input'); - inputPara.textContent = '>'; - inputDiv.appendChild(inputPara); - inputDiv.appendChild(inputForm); - document.body.appendChild(inputDiv); - - if(document.querySelectorAll('div').length > 1) { - inputForm.focus(); - } - - inputForm.addEventListener('change', executeCode); - } - - function executeCode(e) { - try { - var result = geval(e.target.value); - } catch(e) { - var result = 'error — ' + e.message; - } - - var outputDiv = document.createElement('div'); - var outputPara = document.createElement('p'); - - outputDiv.setAttribute('class','output'); - outputPara.textContent = 'Result: ' + result; - outputDiv.appendChild(outputPara); - document.body.appendChild(outputDiv); - - e.target.disabled = true; - e.target.parentNode.style.opacity = '0.5'; - - createInput() - } - - createInput(); - - </script> -</html></pre> -</div> - -<p>{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p> - -<div class="note"> -<p><strong>Note</strong>: In JavaScript, all code instructions should end with a semi-colon (<code>;</code>) — your code may work correctly for single lines, but probably won't when you are writing multiple lines of code together. Try to get into the habit of including it.</p> -</div> - -<p>You can test whether these values now exist in the execution environment by typing just the variable's name, e.g.</p> - -<pre class="brush: js">myName; -myAge;</pre> - -<p>They currently have no value; they are empty containers. When you enter the variable names, you should get a value of <code>undefined</code> returned. If they don't exist, you'll get an error message — try typing in</p> - -<pre class="brush: js">scoobyDoo;</pre> - -<div class="note"> -<p><strong>Note</strong>: Don't confuse a variable that exists but has no value defined with a variable that doesn't exist at all — they are very different things. In the box analogy you saw above, not existing would mean there's no box (variable) for a value to go in. No value defined would mean that there IS a box, but it has no value inside it.</p> -</div> - -<h2 id="Eine_Variable_initialisieren">Eine Variable initialisieren</h2> - -<p>Once you've declared a variable, you can initialize it with a value. You do this by typing the variable name, followed by an equals sign (<code>=</code>), followed by the value you want to give it. For example:</p> - -<pre class="brush: js">myName = 'Chris'; -myAge = 37;</pre> - -<p>Try going back to the console now and typing in these lines. You should see the value you've assigned to the variable returned in the console to confirm it, in each case. Again, you can return your variable values by simply typing their name into the console — try these again:</p> - -<pre class="brush: js">myName; -myAge;</pre> - -<p>You can declare and initialize a variable at the same time, like this:</p> - -<pre class="brush: js">var myName = 'Chris';</pre> - -<p>This is probably what you'll do most of the time, as it is quicker than doing the two actions on two separate lines.</p> - -<div class="note"> -<p><strong>Note</strong>: If you write a multiline JavaScript program that declares and initializes a variable, you can actually declare it after you initialize it and it will still work. This is because variable declarations are generally done first before the rest of the code is executed. This is called <strong>hoisting</strong> — read <a href="/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting">var hoisting</a> for more detail on the subject.</p> -</div> - -<h2 id="Eine_Variable_aktualisieren">Eine Variable aktualisieren</h2> - -<p>Once a variable has been initialized with a value, you can change (or update) that value by simply giving it a different value. Try entering the following lines into your console:</p> - -<pre class="brush: js">myName = 'Bob'; -myAge = 40;</pre> - -<h3 id="An_aside_on_variable_naming_rules">An aside on variable naming rules</h3> - -<p>You can call a variable pretty much anything you like, but there are limitations. Generally, you should stick to just using Latin characters (0-9, a-z, A-Z) and the underscore character.</p> - -<ul> - <li>You shouldn't use other characters because they may cause errors or be hard to understand for an international audience.</li> - <li>Don't use underscores at the start of variable names — this is used in certain JavaScript constructs to mean specific things, so may get confusing.</li> - <li>Don't use numbers at the start of variables. This isn't allowed and will cause an error.</li> - <li>A safe convention to stick to is so-called <a href="https://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms">"lower camel case"</a>, where you stick together multiple words, using lower case for the whole first word and then capitalize subsequent words. We've been using this for our variable names in the article so far.</li> - <li>Make variable names intuitive, so they describe the data they contain. Don't just use single letters/numbers, or big long phrases.</li> - <li>Variables are case sensitive — so <code>myage</code> is a different variable to <code>myAge</code>.</li> - <li>One last point — you also need to avoid using JavaScript reserved words as your variable names — by this, we mean the words that make up the actual syntax of JavaScript! So you can't use words like <code>var</code>, <code>function</code>, <code>let</code>, and <code>for</code> as variable names. Browsers will recognize them as different code items, and so you'll get errors.</li> -</ul> - -<div class="note"> -<p><strong>Note</strong>: You can find a fairly complete list of reserved keywords to avoid at <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords">Lexical grammar — keywords</a>.</p> -</div> - -<p>Good name examples:</p> - -<pre class="example-good">age -myAge -init -initialColor -finalOutputValue -audio1 -audio2</pre> - -<p>Bad name examples:</p> - -<pre class="example-bad">1 -a -_12 -myage -MYAGE -var -Document -skjfndskjfnbdskjfb -thisisareallylongstupidvariablenameman</pre> - -<p>Error-prone name examples:</p> - -<pre class="example-invalid">var -Document -</pre> - -<p>Try creating a few more variables now, with the above guidance in mind.</p> - -<h2 id="Typen_von_Variablen">Typen von Variablen</h2> - -<p>There are a few different types of data we can store in variables. In this section we'll describe these in brief, then in future articles, you'll learn about them in more detail.</p> - -<p>So far we've looked at the first two, but there are others.</p> - -<h3 id="Numbers">Numbers</h3> - -<p>You can store numbers in variables, either whole numbers like 30 (also called integers) or decimal numbers like 2.456 (also called floats or floating point numbers). You don't need to declare variable types in JavaScript, unlike some other programming languages. When you give a variable a number value, you don't include quotes:</p> - -<pre class="brush: js">var myAge = 17;</pre> - -<h3 id="Strings">Strings</h3> - -<p>Strings are pieces of text. When you give a variable a string value, you need to wrap it in single or double quote marks, otherwise, JavaScript will try to interpret it as another variable name.</p> - -<pre class="brush: js">var dolphinGoodbye = 'So long and thanks for all the fish';</pre> - -<h3 id="Booleans">Booleans</h3> - -<p>Booleans are true/false values — they can have two values, <code>true</code> or <code>false</code>. These are generally used to test a condition, after which code is run as appropriate. So for example, a simple case would be:</p> - -<pre class="brush: js">var iAmAlive = true;</pre> - -<p>Whereas in reality it would be used more like this:</p> - -<pre class="brush: js">var test = 6 < 3;</pre> - -<p>This is using the "less than" operator (<code><</code>) to test whether 6 is less than 3. As you might expect, it will return <code>false</code>, because 6 is not less than 3! You will learn a lot more about such operators later on in the course.</p> - -<h3 id="Arrays">Arrays</h3> - -<p>An array is a single object that contains multiple values enclosed in square brackets and separated by commas. Try entering the following lines into your console:</p> - -<pre class="brush: js">var myNameArray = ['Chris', 'Bob', 'Jim']; -var myNumberArray = [10,15,40];</pre> - -<p>Once these arrays are defined, you can access each value by their location within the array. Try these lines:</p> - -<pre class="brush: js">myNameArray[0]; // should return 'Chris' -myNumberArray[2]; // should return 40</pre> - -<p>The square brackets specify an index value corresponding to the position of the value you want returned. You might have noticed that arrays in JavaScript are zero-indexed: the first element is at index 0.</p> - -<p>You'll learn a lot more about arrays in a future article.</p> - -<h3 id="Objects">Objects</h3> - -<p>In programming, an object is a structure of the code that models a real-life object. You can have a simple object that represents a car park and contains information about its width and length, or you could have an object that represents a person, and contains data about their name, height, weight, what language they speak, how to say hello to them, and more.</p> - -<p>Try entering the following line into your console:</p> - -<pre class="brush: js">var dog = { name : 'Spot', breed : 'Dalmatian' };</pre> - -<p>To retrieve the information stored in the object, you can use the following syntax:</p> - -<pre class="brush: js">dog.name</pre> - -<p>We won't be looking at objects any more for now — you can learn more about those in a future module.</p> - -<h2 id="Dynamic_typing">Dynamic typing</h2> - -<p>JavaScript is a "dynamically typed language", which means that, unlike some other languages, you don't need to specify what data type a variable will contain (e.g. numbers, strings, arrays, etc).</p> - -<p>For example, if you declare a variable and give it a value encapsulated in quotes, the browser will treat the variable as a string:</p> - -<pre class="brush: js">var myString = 'Hello';</pre> - -<p>It will still be a string, even if it contains numbers, so be careful:</p> - -<pre class="brush: js">var myNumber = '500'; // oops, this is still a string -typeof myNumber; -myNumber = 500; // much better — now this is a number -typeof myNumber;</pre> - -<p>Try entering the four lines above into your console one by one, and see what the results are. You'll notice that we are using a special operator called <code>typeof</code> — this returns the data type of the variable you pass into it. The first time it is called, it should return <code>string</code>, as at that point the <code>myNumber</code> variable contains a string, <code>'500'</code>. Have a look and see what it returns the second time you call it.</p> - -<h2 id="Zusammenfassung">Zusammenfassung</h2> - -<p>By now you should know a reasonable amount about JavaScript variables and how to create them. In the next article, we'll focus on numbers in more detail, looking at how to do basic math in JavaScript.</p> - -<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Maths", "Learn/JavaScript/First_steps")}}</p> - -<h2 id="In_this_module">In this module</h2> - -<ul> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">The first splash into JavaScript</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li> -</ul> diff --git a/files/de/learn/javascript/objects/inheritance/index.html b/files/de/learn/javascript/objects/inheritance/index.html deleted file mode 100644 index 8eacfbcbfd..0000000000 --- a/files/de/learn/javascript/objects/inheritance/index.html +++ /dev/null @@ -1,440 +0,0 @@ ---- -title: Inheritance in JavaScript -slug: Learn/JavaScript/Objects/Inheritance -translation_of: Learn/JavaScript/Objects/Inheritance ---- -<div>{{LearnSidebar}}</div> - -<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div> - -<p class="summary">Nachdem nun die schmutzigen Details des OOJS erklärt sind, beschäftigt sich dieser Artikel damit, wie "Kinder"-Objektklassen (Konstruktoren) Features von ihren "Eltern"-Klassen vererbt bekommen. Zusätzlich stellen wir Hinweise dazu bereit, wann und wo Du OOJS am besten anwendest und wie mit Klassen im modern ECMAScript Syntax umgegangen wird.</p> - -<table class="learn-box standard-table"> - <tbody> - <tr> - <th scope="row">Voraussetzungen:</th> - <td>Grundsätzliche EDV-Kenntnisse, ein grundlegendes Verständnis für HTML und CSS, mit JavaScript Grundlagen vertraut sein (siehe <a href="/de/docs/Learn/JavaScript/First_steps">Erste Schritte</a> und <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) und Grundlagen zu OOJS (siehe<a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> - </tr> - <tr> - <th scope="row">Lernziel:</th> - <td>Zu verstehen, wie es in JavaScript möglich ist, Vererbung zu implementieren.</td> - </tr> - </tbody> -</table> - -<h2 id="Prototypal_inheritance">Prototypal inheritance</h2> - -<p>So far we have seen some inheritance in action — we have seen how prototype chains work, and how members are inherited going up a chain. But mostly this has involved built-in browser functions. How do we create an object in JavaScript that inherits from another object?</p> - -<p>Let's explore how to do this with a concrete example.</p> - -<h2 id="Getting_started">Getting started</h2> - -<p>First of all, make yourself a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> file (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">running live</a> also). Inside here you'll find the same <code>Person()</code> constructor example that we've been using all the way through the module, with a slight difference — we've defined only the properties inside the constructor:</p> - -<pre class="brush: js notranslate">function Person(first, last, age, gender, interests) { - this.name = { - first, - last - }; - this.age = age; - this.gender = gender; - this.interests = interests; -};</pre> - -<p>The methods are <em>all</em> defined on the constructor's prototype. For example:</p> - -<pre class="brush: js notranslate">Person.prototype.greeting = function() { - alert('Hi! I\'m ' + this.name.first + '.'); -};</pre> - -<div class="note"> -<p><strong>Note</strong>: In the source code, you'll also see <code>bio()</code> and <code>farewell()</code> methods defined. Later you'll see how these can be inherited by other constructors.</p> -</div> - -<p>Say we wanted to create a <code>Teacher</code> class, like the one we described in our initial object-oriented definition, which inherits all the members from <code>Person</code>, but also includes:</p> - -<ol> - <li>A new property, <code>subject</code> — this will contain the subject the teacher teaches.</li> - <li>An updated <code>greeting()</code> method, which sounds a bit more formal than the standard <code>greeting()</code> method — more suitable for a teacher addressing some students at school.</li> -</ol> - -<h2 id="Defining_a_Teacher_constructor_function">Defining a Teacher() constructor function</h2> - -<p>The first thing we need to do is create a <code>Teacher()</code> constructor — add the following below the existing code:</p> - -<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) { - Person.call(this, first, last, age, gender, interests); - - this.subject = subject; -}</pre> - -<p>This looks similar to the Person constructor in many ways, but there is something strange here that we've not seen before — the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code> function. This function basically allows you to call a function defined somewhere else, but in the current context. The first parameter specifies the value of <code>this</code> that you want to use when running the function, and the other parameters are those that should be passed to the function when it is invoked.</p> - -<p>We want the <code>Teacher()</code> constructor to take the same parameters as the <code>Person()</code> constructor it is inheriting from, so we specify them all as parameters in the <code>call()</code> invocation.</p> - -<p>The last line inside the constructor simply defines the new <code>subject</code> property that teachers are going to have, which generic people don't have.</p> - -<p>As a note, we could have simply done this:</p> - -<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) { - this.name = { - first, - last - }; - this.age = age; - this.gender = gender; - this.interests = interests; - this.subject = subject; -}</pre> - -<p>But this is just redefining the properties anew, not inheriting them from <code>Person()</code>, so it defeats the point of what we are trying to do. It also takes more lines of code.</p> - -<h3 id="Inheriting_from_a_constructor_with_no_parameters">Inheriting from a constructor with no parameters</h3> - -<p>Note that if the constructor you are inheriting from doesn't take its property values from parameters, you don't need to specify them as additional arguments in <code>call()</code>. So, for example, if you had something really simple like this:</p> - -<pre class="brush: js notranslate">function Brick() { - this.width = 10; - this.height = 20; -}</pre> - -<p>You could inherit the <code>width</code> and <code>height</code> properties by doing this (as well as the other steps described below, of course):</p> - -<pre class="brush: js notranslate">function BlueGlassBrick() { - Brick.call(this); - - this.opacity = 0.5; - this.color = 'blue'; -}</pre> - -<p>Note that we've only specified <code>this</code> inside <code>call()</code> — no other parameters are required as we are not inheriting any properties from the parent that are set via parameters.</p> - -<h2 id="Setting_Teachers_prototype_and_constructor_reference">Setting Teacher()'s prototype and constructor reference</h2> - -<p>All is good so far, but we have a problem. We have defined a new constructor, and it has a <code>prototype</code> property, which by default just contains an object with a reference to the constructor function itself. It does not contain the methods of the Person constructor's <code>prototype</code> property. To see this, enter <code>Object.getOwnPropertyNames(Teacher.prototype)</code> into either the text input field or your JavaScript console. Then enter it again, replacing <code>Teacher</code> with <code>Person</code>. Nor does the new constructor <em>inherit</em> those methods. To see this, compare the outputs of <code>Person.prototype.greeting</code> and <code>Teacher.prototype.greeting</code>. We need to get <code>Teacher()</code> to inherit the methods defined on <code>Person()</code>'s prototype. So how do we do that?</p> - -<ol> - <li>Add the following line below your previous addition: - <pre class="brush: js notranslate">Teacher.prototype = Object.create(Person.prototype);</pre> - Here our friend <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> comes to the rescue again. In this case we are using it to create a new object and make it the value of <code>Teacher.prototype</code>. The new object has <code>Person.prototype</code> as its prototype and will therefore inherit, if and when needed, all the methods available on <code>Person.prototype</code>.</li> - <li>We need to do one more thing before we move on. After adding the last line, <code>Teacher.</code><code>prototype</code>'s <code>constructor</code> property is now equal to <code>Person()</code>, because we just set <code>Teacher.prototype</code> to reference an object that inherits its properties from <code>Person.prototype</code>! Try saving your code, loading the page in a browser, and entering <code>Teacher.prototype.constructor</code> into the console to verify.</li> - <li>This can become a problem, so we need to set this right. You can do so by going back to your source code and adding the following line at the bottom: - <pre class="brush: js notranslate">Object.defineProperty(Teacher.prototype, 'constructor', { - value: Teacher, - enumerable: false, // so that it does not appear in 'for in' loop - writable: true });</pre> - </li> - <li>Now if you save and refresh, entering <code>Teacher.prototype.constructor</code> should return <code>Teacher()</code>, as desired, plus we are now inheriting from <code>Person()</code>!</li> -</ol> - -<h2 id="Giving_Teacher_a_new_greeting_function">Giving Teacher() a new greeting() function</h2> - -<p>To finish off our code, we need to define a new <code>greeting()</code> function on the <code>Teacher()</code> constructor.</p> - -<p>The easiest way to do this is to define it on <code>Teacher()</code>'s prototype — add the following at the bottom of your code:</p> - -<pre class="brush: js notranslate">Teacher.prototype.greeting = function() { - let prefix; - - if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { - prefix = 'Mr.'; - } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { - prefix = 'Ms.'; - } else { - prefix = 'Mx.'; - } - - alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); -};</pre> - -<p>This alerts the teacher's greeting, which also uses an appropriate name prefix for their gender, worked out using a conditional statement.</p> - -<h2 id="Trying_the_example_out">Trying the example out</h2> - -<p>Now that you've entered all the code, try creating an object instance from <code>Teacher()</code> by putting the following at the bottom of your JavaScript (or something similar of your choosing):</p> - -<pre class="brush: js notranslate">let teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre> - -<p>Now save and refresh, and try accessing the properties and methods of your new <code>teacher1</code> object, for example:</p> - -<pre class="brush: js notranslate">teacher1.name.first; -teacher1.interests[0]; -teacher1.bio(); -teacher1.subject; -teacher1.greeting(); -teacher1.farewell();</pre> - -<p>These should all work just fine. The queries on lines 1, 2, 3, and 6 access members inherited from the generic <code>Person()</code> constructor (class). The query on line 4 accesses a member that is available only on the more specialized <code>Teacher()</code> constructor (class). The query on line 5 would have accessed a member inherited from <code>Person()</code>, except for the fact that <code>Teacher()</code> has its own member with the same name, so the query accesses that member.</p> - -<div class="note"> -<p><strong>Note</strong>: If you have trouble getting this to work, compare your code to our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">running live</a> also).</p> -</div> - -<p>The technique we covered here is not the only way to create inheriting classes in JavaScript, but it works OK, and it gives you a good idea about how to implement inheritance in JavaScript.</p> - -<p>You might also be interested in checking out some of the new {{glossary("ECMAScript")}} features that allow us to do inheritance more cleanly in JavaScript (see <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). We didn't cover those here, as they are not yet supported very widely across browsers. All the other code constructs we discussed in this set of articles are supported as far back as IE9 or earlier, and there are ways to achieve earlier support than that.</p> - -<p>A common way is to use a JavaScript library — most of the popular options have an easy set of functionality available for doing inheritance more easily and quickly. <a href="http://coffeescript.org/#classes">CoffeeScript</a> for example provides <code>class</code>, <code>extends</code>, etc.</p> - -<h2 id="A_further_exercise">A further exercise</h2> - -<p>In our <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">OOP theory section</a>, we also included a <code>Student</code> class as a concept, which inherits all the features of <code>Person</code>, and also has a different <code>greeting()</code> method from <code>Person</code> that is much more informal than the <code>Teacher</code>'s greeting. Have a look at what the student's greeting looks like in that section, and try implementing your own <code>Student()</code> constructor that inherits all the features of <code>Person()</code>, and implements the different <code>greeting()</code> function.</p> - -<div class="note"> -<p><strong>Note</strong>: If you have trouble getting this to work, have a look at our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">running live</a> also).</p> -</div> - -<h2 id="Object_member_summary">Object member summary</h2> - -<p>To summarize, you've got four types of property/method to worry about:</p> - -<ol> - <li>Those defined inside a constructor function that are given to object instances. These are fairly easy to spot — in your own custom code, they are the members defined inside a constructor using the <code>this.x = x</code> type lines; in built in browser code, they are the members only available to object instances (usually created by calling a constructor using the <code>new</code> keyword, e.g. <code>let myInstance = new myConstructor()</code>).</li> - <li>Those defined directly on the constructor themselves, that are available only on the constructor. These are commonly only available on built-in browser objects, and are recognized by being chained directly onto a constructor, <em>not</em> an instance. For example, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>. These are also known as <strong>static properties/methods</strong>.</li> - <li>Those defined on a constructor's prototype, which are inherited by all instances and inheriting object classes. These include any member defined on a Constructor's <code>prototype</code> property, e.g. <code>myConstructor.prototype.x()</code>.</li> - <li>Those available on an object instance, which can either be an object created when a constructor is instantiated like we saw above (so for example <code>var teacher1 = new Teacher( name = 'Chris' );</code> and then <code>teacher1.name</code>), or an object literal (<code>let teacher1 = { name = 'Chris' }</code> and then <code>teacher1.name</code>).</li> -</ol> - -<p>If you are not sure which is which, don't worry about it just yet — you are still learning, and familiarity will come with practice.</p> - -<h2 id="ECMAScript_2015_Classes">ECMAScript 2015 Classes</h2> - -<p>ECMAScript 2015 introduces <a href="/en-US/docs/Web/JavaScript/Reference/Classes">class syntax</a> to JavaScript as a way to write reusable classes using easier, cleaner syntax, which is more similar to classes in C++ or Java. In this section we'll convert the Person and Teacher examples from prototypal inheritance to classes, to show you how it's done.</p> - -<div class="note"> -<p><strong>Note</strong>: This modern way of writing classes is supported in all modern browsers, but it is still worth knowing about the underlying prototypal inheritance in case you work on a project that requires supporting a browser that doesn't support this syntax (most notably Internet Explorer).</p> -</div> - -<p>Let's look at a rewritten version of the Person example, class-style:</p> - -<pre class="brush: js notranslate">class Person { - constructor(first, last, age, gender, interests) { - this.name = { - first, - last - }; - this.age = age; - this.gender = gender; - this.interests = interests; - } - - greeting() { - console.log(`Hi! I'm ${this.name.first}`); - }; - - farewell() { - console.log(`${this.name.first} has left the building. Bye for now!`); - }; -} -</pre> - -<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">class</a> statement indicates that we are creating a new class. Inside this block, we define all the features of the class:</p> - -<ul> - <li>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">constructor()</a></code> method defines the constructor function that represents our <code>Person</code> class.</li> - <li><code>greeting()</code> and <code>farewell()</code> are class methods. Any methods you want associated with the class are defined inside it, after the constructor. In this example, we've used <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">template literals</a> rather than string concatenation to make the code easier to read.</li> -</ul> - -<p>We can now instantiate object instances using the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> operator</a>, in just the same way as we did before:</p> - -<pre class="brush: js notranslate">let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']); -han.greeting(); -// Hi! I'm Han - -let leia = new Person('Leia', 'Organa', 19, 'female', ['Government']); -leia.farewell(); -// Leia has left the building. Bye for now -</pre> - -<div class="note"> -<p><strong>Note</strong>: Under the hood, your classes are being converted into Prototypal Inheritance models — this is just syntactic sugar. But I'm sure you'll agree that it's easier to write.</p> -</div> - -<h3 id="Inheritance_with_class_syntax">Inheritance with class syntax</h3> - -<p>Above we created a class to represent a person. They have a series of attributes that are common to all people; in this section we'll create our specialized <code>Teacher</code> class, making it inherit from <code>Person</code> using modern class syntax. This is called creating a subclass or subclassing.</p> - -<p>To create a subclass we use the <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends keyword</a> to tell JavaScript the class we want to base our class on,</p> - -<pre class="brush: js notranslate">class Teacher extends Person { - constructor(subject, grade) { - this.subject = subject; - this.grade = grade; - } -}</pre> - -<p>but there's a little catch.</p> - -<p>Unlike old-school constructor functions where the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> operator</a> does the initialization of <code>this</code> to a newly-allocated object, this isn't automatically initialized for a class defined by the <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a> keyword, i.e the sub-classes.</p> - -<p>Therefore running the above code will give an error:</p> - -<pre class="brush: js notranslate">Uncaught ReferenceError: Must call super constructor in derived class before -accessing 'this' or returning from derived constructor</pre> - -<p>For sub-classes, the <code>this</code> intialization to a newly allocated object is always dependant on the parent class constructor, i.e the constructor function of the class from which you're extending.</p> - -<p>Here we are extending the <code>Person</code> class — the <code>Teacher</code> sub-class is an extension of the <code>Person</code> class. So for <code>Teacher</code>, the <code>this</code> initialization is done by the <code>Person</code> constructor.</p> - -<p>To call the parent constructor we have to use the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> operator</a>, like so:</p> - -<pre class="brush: js notranslate">class Teacher extends Person { - constructor(subject, grade) { - super(); // Now 'this' is initialized by calling the parent constructor. - this.subject = subject; - this.grade = grade; - } -}</pre> - -<p>There is no point having a sub-class if it doesn't inherit properties from the parent class.<br> - It is good then, that the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> operator</a> also accepts arguments for the parent constructor.</p> - -<p>Looking back to our <code>Person</code> constructor, we can see it has the following block of code in its constructor method:</p> - -<pre class="brush: js notranslate"> constructor(first, last, age, gender, interests) { - this.name = { - first, - last - }; - this.age = age; - this.gender = gender; - this.interests = interests; -} </pre> - -<p>Since the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super()</a></code> operator is actually the parent class constructor, passing it the necessary arguments of the <code>Parent</code> class constructor will also initialize the parent class properties in our sub-class, thereby inheriting it:</p> - -<pre class="brush: js notranslate">class Teacher extends Person { - constructor(first, last, age, gender, interests, subject, grade) { - super(first, last, age, gender, interests); - - // subject and grade are specific to Teacher - this.subject = subject; - this.grade = grade; - } -} -</pre> - -<p>Now when we instantiate <code>Teacher</code> object instances, we can call methods and properties defined on both <code>Teacher</code>and <code>Person</code> as we'd expect:</p> - -<pre class="brush: js notranslate">let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5); -snape.greeting(); // Hi! I'm Severus. -snape.farewell(); // Severus has left the building. Bye for now. -snape.age // 58 -snape.subject; // Dark arts -</pre> - -<p>Like we did with Teachers, we could create other subclasses of <code>Person</code> to make them more specialized without modifying the base class.</p> - -<div class="note"> -<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-class-inheritance.html">es2015-class-inheritance.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-class-inheritance.html">see it live also</a>).</p> -</div> - -<h2 id="Getters_and_Setters">Getters and Setters</h2> - -<p>There may be times when we want to change the values of an attribute in the classes we create or we don't know what the final value of an attribute will be. Using the <code>Teacher</code> example, we may not know what subject the teacher will teach before we create them, or their subject may change between terms.</p> - -<p>We can handle such situations with getters and setters.</p> - -<p>Let's enhance the Teacher class with getters and setters. The class starts the same as it was the last time we looked at it.</p> - -<p>Getters and setters work in pairs. A getter returns the current value of the variable and its corresponding setter changes the value of the variable to the one it defines.</p> - -<p>The modified <code>Teacher</code> class looks like this:</p> - -<pre class="brush: js notranslate">class Teacher extends Person { - constructor(first, last, age, gender, interests, subject, grade) { - super(first, last, age, gender, interests); - // subject and grade are specific to Teacher - this._subject = subject; - this.grade = grade; - } - - get subject() { - return this._subject; - } - - set subject(newSubject) { - this._subject = newSubject; - } -} -</pre> - -<p>In our class above we have a getter and setter for the <code>subject</code> property. We use <strong><code>_</code> </strong> to create a separate value in which to store our name property. Without using this convention, we would get errors every time we called get or set. At this point:</p> - -<ul> - <li>To show the current value of the <code>_subject</code> property of the <code>snape</code> object we can use the <code>snape.subject</code> getter method.</li> - <li>To assign a new value to the <code>_subject</code> property we can use the <code>snape.subject="new value"</code> setter method.</li> -</ul> - -<p>The example below shows the two features in action:</p> - -<pre class="brush: js notranslate">// Check the default value -console.log(snape.subject) // Returns "Dark arts" - -// Change the value -snape.subject = "Balloon animals" // Sets _subject to "Balloon animals" - -// Check it again and see if it matches the new value -console.log(snape.subject) // Returns "Balloon animals" -</pre> - -<div class="note"> -<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-getters-setters.html">es2015-getters-setters.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-getters-setters.html">see it live also</a>).</p> -</div> - -<div class="blockIndicator note"> -<p><strong>Note:</strong> Getters and setters can be very useful at times, for example when you want to run some code every time a property is requested or set. For simple cases, however, plain property access without a getter or setter will do just fine.</p> -</div> - -<h2 id="When_would_you_use_inheritance_in_JavaScript">When would you use inheritance in JavaScript?</h2> - -<p>Particularly after this last article, you might be thinking "woo, this is complicated". Well, you are right. Prototypes and inheritance represent some of the most complex aspects of JavaScript, but a lot of JavaScript's power and flexibility comes from its object structure and inheritance, and it is worth understanding how it works.</p> - -<p>In a way, you use inheritance all the time. Whenever you use various features of a Web API , or methods/properties defined on a built-in browser object that you call on your strings, arrays, etc., you are implicitly using inheritance.</p> - -<p>In terms of using inheritance in your own code, you probably won't use it often, especially to begin with, and in small projects. It is a waste of time to use objects and inheritance just for the sake of it when you don't need them. But as your code bases get larger, you are more likely to find a need for it. If you find yourself starting to create a number of objects that have similar features, then creating a generic object type to contain all the shared functionality and inheriting those features in more specialized object types can be convenient and useful.</p> - -<div class="note"> -<p><strong>Note</strong>: Because of the way JavaScript works, with the prototype chain, etc., the sharing of functionality between objects is often called <strong>delegation</strong>. Specialized objects delegate functionality to a generic object type.</p> -</div> - -<p>When using inheritance, you are advised to not have too many levels of inheritance, and to keep careful track of where you define your methods and properties. It is possible to start writing code that temporarily modifies the prototypes of built-in browser objects, but you should not do this unless you have a really good reason. Too much inheritance can lead to endless confusion, and endless pain when you try to debug such code.</p> - -<p>Ultimately, objects are just another form of code reuse, like functions or loops, with their own specific roles and advantages. If you find yourself creating a bunch of related variables and functions and want to track them all together and package them neatly, an object is a good idea. Objects are also very useful when you want to pass a collection of data from one place to another. Both of these things can be achieved without use of constructors or inheritance. If you only need a single instance of an object, then you are probably better off just using an object literal, and you certainly don't need inheritance.</p> - -<h2 id="Alternatives_for_extending_the_prototype_chain">Alternatives for extending the prototype chain</h2> - -<p>In JavaScript, there are several different ways to extend the prototype of an object aside from what we've shown above. To find out more about the other ways, visit our <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Different_ways_to_create_objects_and_the_resulting_prototype_chain">Inheritance and the prototype chain</a> article.</p> - -<h2 id="Test_your_skills!">Test your skills!</h2> - -<p>You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see <a href="/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript">Test your skills: Object-oriented JavaScript</a>.</p> - -<h2 id="Summary">Summary</h2> - -<p>This article has covered the remainder of the core OOJS theory and syntax that we think you should know now. At this point you should understand JavaScript object and OOP basics, prototypes and prototypal inheritance, how to create classes (constructors) and object instances, add features to classes, and create subclasses that inherit from other classes.</p> - -<p>In the next article we'll have a look at how to work with JavaScript Object Notation (JSON), a common data exchange format written using JavaScript objects.</p> - -<h2 id="See_also">See also</h2> - -<ul> - <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li> - <li><a href="https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition">Secrets of the JavaScript Ninja</a>, Chapter 7 — A good book on advanced JavaScript concepts and techniques, by John Resig, Bear Bibeault, and Josip Maras. Chapter 7 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li> - <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/README.md">You Don't Know JS: this & Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li> -</ul> - -<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p> - -<h2 id="In_this_module">In this module</h2> - -<ul> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> - <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> -</ul> |