JavaScript là Gì?

This translation is incomplete. Please help translate this article from English

Chào mừng đến khóa học JavaScript cơ bản của MDN! Trong bài đầu tiên chúng ta sẽ nhìn nhận JavaScript từ góc độ tổng quát, trả lời các câu hỏi như "JavaScript là gì?" và "nó có khả năng gì?" cũng như giúp bạn làm quen với các chức năng của JavaScript.

Yêu cầu:

Sử dụng máy cơ bản, hiểu HTML và CSS mức độ căn bản

Mục tiêu:

Làm quen với JavaScript, tìm hiểu về ứng dụng của JavaScript và cách tích hợp chúng vào một trang web.

A high-level definition

JavaScript là một ngôn ngữ lập trình hoặc ngôn ngữ kịch bản cho phép triển khai những chức năng phức tạp trên trang web như hiển thị các cập nhật nội dung kịp thời, tương tác với bản đồ, hoạt cảnh 2D/3D vv... - điều có sự hỗ trợ của JavaScript. Nó là lớp thứ ba của chiếc bánh tiêu chuẩn của các công nghệ web, hai trong số chúng (HTML và CSS) đã được chúng tôi trình bày rất chi tiết trong các phần khác của Learning Area.

  • HTML là ngôn ngữ đánh dấu được sử dụng để cấu thành nội dung và mang đến ngữ nghĩa cho trang web, ví dụ như định danh cho các đoạn văn, tiêu đề, dữ liệu dạng bảng hoặc nhúng hình ảnh, video vào trang web. 
  • CSS là một ngôn ngữ định dạng được áp dụng để tạo nên "vẻ ngoài" của một trang web, ví dụ thiết lập màu nền và font chữ, bố trí nội dung dựa theo mô hình cột.
  • JavaScript là ngôn ngữ kịch bản cho phép tạo ra trang web động - cập nhật nội dung theo ngữ cảnh, điều khiển đa phương tiện, hoạt cảnh các hình ảnh và nhiều thứ hay ho khác. (Dĩ nhiên không phải mọi thứ, nhưng chỉ với một vài dòng code, JavaScript có thể làm được nhiều điều đáng kinh ngạc.)

Ba lớp công nghệ xếp chồng lên nhau một cách thích hợp. Hãy xem xét ví dụ một đoạn văn bản đơn giản. Chúng ta có thể đánh dấu đoạn văn bảng bằng HTML.

<p>Player 1: Chris</p>

Sau đó thêm một vài đoạn CSS giúp tăng tính thẩm mỹ cho đoạn văn:

p {
  font-family: 'helvetica neue', helvetica, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid rgba(0,0,200,0.6);
  background: rgba(0,0,200,0.3);
  color: rgba(0,0,200,0.6);
  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
  border-radius: 10px;
  padding: 3px 10px;
  display: inline-block;
  cursor: pointer;
}

Và cuối cùng, chúng ta có thể áp dụng JavaScript vào đoạn văn để tăng tính tương tác.

const para = document.querySelector('p');

para.addEventListener('click', updateName);

function updateName() {
  let name = prompt('Enter a new name');
  para.textContent = 'Player 1: ' + name;
}

Thử nhấp vào phiên bản cuối cùng của đoạn văn để thấy cách nó hoạt động (bạn cũng có thể tìm thấy ví dụ này trên GitHub — xem mã nguồn: source code, hoặc chạy trực tiếp: run it live)!

JavaScript có thể làm được nhiều hơn thế  — Cùng khám phá chi tiết hơn.

So what can it really do?

Bên trong ngôn ngữ JavaScript bao gồm một vài tính năng lập trình phổ biến cho phép bạn thực hiện một vài điều như:

  • Lưu trữ các giá trị (thông tin) trong các biến (variables). Đại loại như ở ví dụ bên trên, chúng tôi yêu cầu nhập một tên mới sau đó lưu trữ tên vừa nhập trong một biến gọi là name.
  • Thao tác trên các đoạn văn bản (còn gọi là chuỗi - strings trong lập trình). Trong ví dụ trên, chúng tôi lấy chuỗi "Player 1:" và xâu nó vào biến name để tạo đoạn văn bản hoàn chỉnh là ''Player 1: Chris".
  • Chạy code phản hồi lại những sự kiện đang xãy ra trên trang web. Chúng tôi đã dùng một sự kiện click trong ví dụ bên trên để phát hiện sự kiện nhấp chuột vào nút nhấn và chạy code tương ứng để cập nhật đoạn văn bản.
  • Và nhiều hơn thế nữa!

Tuy nhiên thứ mà thậm chí còn thú vị hơn nữa là các lớp tính năng (functionality) được xây dựng trên lõi của ngôn ngữ JavaScript. Cái được gọi là Giao Diện Lập Trình Ứng Dụng (Application Programming Interfaces-APIs) trao thêm cho bạn siêu sức mạnh để sử dụng trong code JavaScript.

APIs là các bộ code được dựng sẵn cho phép một nhà pháp triển (developer) triển khai các chương trình mà nếu thiếu nó sẽ khó hoặc bất khả thi để triển khai. Chúng hoạt động trong lập trình tương tự như những bộ nội thất làm sẵn cho việc xây nhà — sẽ dễ dàng hơn nhiều nếu lắp ráp một kệ sách với gỗ đã gia công theo thiết kế và ốc vít có sẵn hơn là tự tìm gỗ nguyên liệu, tự gia công theo kích cỡ đã thiết kết, tìm ốc vít đúng cỡ rồi lắp ráp thành một kệ sách.

APIs thường được chia thành hai loại:

Browser APIs (APIs Trình Duyệt) được tích hợp sẵn trong trình duyệt web, có khả năng phơi bày dữ liệu từ môi trường máy tính xung quanh hoặc làm những điều phức tạp hữu ích. Ví dụ:

  • DOM (Document Object Model) API cho phép bạn điều khiển HTML và CSS, tạo mới, loại bỏ và thay đổi HTML, áp dụng các định dạng (style) mới vào trang của bạn một cách linh hoạt vv... Mỗi khi bạn nhìn thấy một cửa sổ bật lên (popup window) trên một trang hoặc một vài nội dung mới được hiển thị (như chúng ta được thấy trong ví dụ đơn giản ở trên) chẳng hạn, đó là các hoạt động điển hình của DOM.
  • Geolocation API tiếp nhận thông tin địa lí. Đây là cách Google Maps tìm vị trí của bạn và định vị nó trên bản đồ.
  • Canvas và WebGL APIs cho phép bạn tạo hoạt cảnh đồ họa 2D và 3D. Các lập trình viên đang sáng tạo những thứ hay ho nhờ sử dụng các công nghệ web này — xem Chrome Experiments và webglsamples để biết thêm.
  • Audio and Video APIs như HTMLMediaElement và WebRTC cho phép bạn làm những điều thứ thật sự thú vị với đa phương tiện (multimedia) như chạy âm thanh (audio) và video ngay trong trang web hoặc thu video từ webcam và hiển thị nó trên máy tính của người khác  (try our simple Snapshot demo to get the idea).

Note: Many of the above demos won't work in an older browser — when experimenting, it's a good idea to use a modern browser like Firefox, Chrome, Edge or Opera to run your code in. You will need to consider cross browser testing in more detail when you get closer to delivering production code (i.e. real code that real customers will use).

Third party APIs are not built into the browser by default, and you generally have to grab their code and information from somewhere on the Web. For example:

  • The Twitter API allows you to do things like displaying your latest tweets on your website.
  • The Google Maps API and OpenStreetMap API allows you to embed custom maps into your website, and other such functionality.

Note: These APIs are advanced, and we'll not be covering any of these in this module. You can find out much more about these in our Client-side web APIs module.

There's a lot more available, too! However, don't get over excited just yet. You won't be able to build the next Facebook, Google Maps, or Instagram after studying JavaScript for 24 hours — there are a lot of basics to cover first. And that's why you're here — let's move on!

What is JavaScript doing on your page?

Here we'll start actually looking at some code, and while doing so explore what actually happens when you run some JavaScript in your page.

Let's briefly recap the story of what happens when you load a web page in a browser (first talked about in our How CSS works article). When you load a web page in your browser, you are running your code (the HTML, CSS, and JavaScript) inside an execution environment (the browser tab). This is like a factory that takes in raw materials (the code) and outputs a product (the web page).

The JavaScript is executed by the browser's JavaScript engine, after the HTML and CSS have been assembled and put together into a web page. This ensures that the structure and style of the page are already in place by the time the JavaScript starts to run.

This is a good thing, as a very common use of JavaScript is to dynamically modify HTML and CSS to update a user interface, via the Document Object Model API (as mentioned above). If the JavaScript loaded and tried to run before the HTML and CSS were there to affect, then errors would occur.

Browser security

Each browser tab is its own separate bucket for running code in (these buckets are called "execution environments" in technical terms) — this means that in most cases the code in each tab is run completely separately, and the code in one tab cannot directly affect the code in another tab — or on another website. This is a good security measure — if this were not the case, then pirates could start writing code to steal information from other websites, and other such bad things.

Note: There are ways to send code and data between different websites/tabs in a safe manner, but these are advanced techniques that we won't cover in this course.

JavaScript running order

When the browser encounters a block of JavaScript, it generally runs it in order, from top to bottom. This means that you need to be careful what order you put things in. For example, let's return to the block of JavaScript we saw in our first example:

const para = document.querySelector('p');

para.addEventListener('click', updateName);

function updateName() {
  let name = prompt('Enter a new name');
  para.textContent = 'Player 1: ' + name;
}

Here we are selecting a text paragraph (line 1), then attaching an event listener to it (line 3) so that when the paragraph is clicked, the updateName() code block (lines 5–8) is run. The updateName() code block (these types of reusable code blocks are called "functions") asks the user for a new name, and then inserts that name into the paragraph to update the display.

If you swapped the order of the first two lines of code, it would no longer work — instead, you'd get an error returned in the browser developer consoleTypeError: para is undefined. This means that the para object does not exist yet, so we can't add an event listener to it.

Note: This is a very common error — you need to be careful that the objects referenced in your code exist before you try to do stuff to them.

Interpreted versus compiled code

You might hear the terms interpreted and compiled in the context of programming. In interpreted languages, the code is run from top to bottom and the result of running the code is immediately returned. You don't have to transform the code into a different form before the browser runs it.

Compiled languages on the other hand are transformed (compiled) into another form before they are run by the computer. For example, C/C++ are compiled into assembly language that is then run by the computer.

JavaScript is a lightweight interpreted programming language. Both approaches have different advantages, which we won't discuss at this point.

Server-side versus client-side code

You might also hear the terms server-side and client-side code, especially in the context of web development. Client-side code is code that is run on the user's computer — when a web page is viewed, the page's client-side code is downloaded, then run and displayed by the browser. In this module we are explicitly talking about client-side JavaScript.

Server-side code on the other hand is run on the server, then its results are downloaded and displayed in the browser. Examples of popular server-side web languages include PHP, Python, Ruby, ASP.NET and... JavaScript! JavaScript can also be used as a server-side language, for example in the popular Node.js environment — you can find out more about server-side JavaScript in our Dynamic Websites – Server-side programming topic.

Dynamic versus static code

The word dynamic is used to describe both client-side JavaScript, and server-side languages — it refers to the ability to update the display of a web page/app to show different things in different circumstances, generating new content as required. Server-side code dynamically generates new content on the server, e.g. pulling data from a database, whereas client-side JavaScript dynamically generates new content inside the browser on the client, e.g. creating a new HTML table, filling it with data requested from the server, then displaying the table in a web page shown to the user. The meaning is slightly different in the two contexts, but related, and both approaches (server-side and client-side) usually work together.

A web page with no dynamically updating content is referred to as static — it just shows the same content all the time.

How do you add JavaScript to your page?

JavaScript is applied to your HTML page in a similar manner to CSS. Whereas CSS uses <link> elements to apply external stylesheets and <style> elements to apply internal stylesheets to HTML, JavaScript only needs one friend in the world of HTML — the <script> element. Let's learn how this works.

Internal JavaScript

  1. First of all, make a local copy of our example file apply-javascript.html. Save it in a directory somewhere sensible.
  2. Open the file in your web browser and in your text editor. You'll see that the HTML creates a simple web page containing a clickable button.
  3. Next, go to your text editor and add the following in your head — just before your closing </head> tag:
    <script>
    
      // JavaScript goes here
    
    </script>
  4. Now we'll add some JavaScript inside our <script> element to make the page do something more interesting — add the following code just below the "// JavaScript goes here" line:
    document.addEventListener("DOMContentLoaded", function() {
      function createParagraph() {
        let para = document.createElement('p');
        para.textContent = 'You clicked the button!';
        document.body.appendChild(para);
      }
    
      const buttons = document.querySelectorAll('button');
    
      for(let i = 0; i < buttons.length ; i++) {
        buttons[i].addEventListener('click', createParagraph);
      }
    });
  5. Save your file and refresh the browser — now you should see that when you click the button, a new paragraph is generated and placed below.

Note: If your example doesn't seem to work, go through the steps again and check that you did everything right. Did you save your local copy of the starting code as a .html file? Did you add your <script> element just before the </head> tag? Did you enter the JavaScript exactly as shown? JavaScript is case sensitive, and very fussy, so you need to enter the syntax exactly as shown, otherwise it may not work.

Note: You can see this version on GitHub as apply-javascript-internal.html (see it live too).

External JavaScript

This works great, but what if we wanted to put our JavaScript in an external file? Let's explore this now.

  1. First, create a new file in the same directory as your sample HTML file. Call it script.js — make sure it has that .js filename extension, as that's how it is recognized as JavaScript.
  2. Replace your current <script> element with the following:
    <script src="script.js" defer></script>
  3. Inside script.js, add the following script:
    function createParagraph() {
      let para = document.createElement('p');
      para.textContent = 'You clicked the button!';
      document.body.appendChild(para);
    }
    
    const buttons = document.querySelectorAll('button');
    
    for(let i = 0; i < buttons.length ; i++) {
      buttons[i].addEventListener('click', createParagraph);
    }
  4. Save and refresh your browser, and you should see the same thing! It works just the same, but now we've got our JavaScript in an external file. This is generally a good thing in terms of organizing your code and making it reusable across multiple HTML files. Plus, the HTML is easier to read without huge chunks of script dumped in it.

Note: You can see this version on GitHub as apply-javascript-external.html and script.js (see it live too).

Inline JavaScript handlers

Note that sometimes you'll come across bits of actual JavaScript code living inside HTML. It might look something like this:

function createParagraph() {
  let para = document.createElement('p');
  para.textContent = 'You clicked the button!';
  document.body.appendChild(para);
}
<button onclick="createParagraph()">Click me!</button>

You can try this version of our demo below.

This demo has exactly the same functionality as in the previous two sections, except that the <button> element includes an inline onclick handler to make the function run when the button is pressed.

Please don't do this, however. It is bad practice to pollute your HTML with JavaScript, and it is inefficient — you'd have to include the onclick="createParagraph()" attribute on every button you wanted the JavaScript to apply to.

Using a pure JavaScript construct allows you to select all the buttons using one instruction. The code we used above to serve this purpose looks like this:

const buttons = document.querySelectorAll('button');

for(let i = 0; i < buttons.length ; i++) {
  buttons[i].addEventListener('click', createParagraph);
}

This might be a bit longer than the onclick attribute, but it will work for all buttons — no matter how many are on the page, nor how many are added or removed. The JavaScript does not need to be changed.

Note: Try editing your version of apply-javascript.html and add a few more buttons into the file. When you reload, you should find that all of the buttons when clicked will create a paragraph. Neat, huh?

Script loading strategies

There are a number of issues involved with getting scripts to load at the right time. Nothing is as simple as it seems! A common problem is that all the HTML on a page is loaded in the order in which it appears. If you are using JavaScript to manipulate elements on the page (or more accurately, the Document Object Model), your code won't work if the JavaScript is loaded and parsed before the HTML you are trying to do something to.

In the above code examples, in the internal and external examples the JavaScript is loaded and run in the head of the document, before the HTML body is parsed. This could cause an error, so we've used some constructs to get around it.

In the internal example, you can see this structure around the code:

document.addEventListener("DOMContentLoaded", function() {
  ...
});

This is an event listener, which listens for the browser's "DOMContentLoaded" event, which signifies that the HTML body is completely loaded and parsed. The JavaScript inside this block will not run until after that event is fired, therefore the error is avoided (you'll learn about events later in the course).

In the external example, we use a more modern JavaScript feature to solve the problem, the defer attribute, which tells the browser to continue downloading the HTML content once the <script> tag element has been reached.

<script src="script.js" defer></script>

In this case both the script and the HTML will load simultaneously and the code will work.

Note: In the external case, we did not need to use the DOMContentLoaded event because the defer attribute solved the problem for us. We didn't use the defer solution for the internal JavaScript example because defer only works for external scripts.

An old-fashioned solution to this problem used to be to put your script element right at the bottom of the body (e.g. just before the </body> tag), so that it would load after all the HTML has been parsed. The problem with this solution is that loading/parsing of the script is completely blocked until the HTML DOM has been loaded. On larger sites with lots of JavaScript, this can cause a major performance issue, slowing down your site.

async and defer

There are actually two ways we can bypass the problem of the blocking script — async and defer. Let's look at the difference between these two.

Async scripts will download the script without blocking rendering the page and will execute it as soon as the script finishes downloading. You get no guarantee that scripts will run in any specific order, only that they will not stop the rest of the page from displaying. It is best to use async when the scripts in the page run independently from each other and depend on no other script on the page.

For example, if you have the following script elements:

<script async src="js/vendor/jquery.js"></script>

<script async src="js/script2.js"></script>

<script async src="js/script3.js"></script>

You can't rely on the order the scripts will load in. jquery.js may load before or after script2.js and script3.js and if this is the case, any functions in those scripts depending on jquery will produce an error because jquery will not be defined at the time the script runs.

defer will run the scripts in the order they appear in the page and execute them as soon as the script and content are downloaded:

<script defer src="js/vendor/jquery.js"></script>

<script defer src="js/script2.js"></script>

<script defer src="js/script3.js"></script>

All the scripts with the defer attribute will load in the order they appear on the page. So in the second example, we can be sure that jquery.js will load before script2.js and script3.js and that script2.js will load before script3.js.

To summarize:

  • If your scripts don't need to wait for parsing and can run independently without dependencies, then use async.
  • If your scripts need to wait for parsing and depend on other scripts load them using defer and put their corresponding <script> elements in the order you want the browser to execute them.

Comments

As with HTML and CSS, it is possible to write comments into your JavaScript code that will be ignored by the browser, and exist simply to provide instructions to your fellow developers on how the code works (and you, if you come back to your code after six months and can't remember what you did). Comments are very useful, and you should use them often, particularly for larger applications. There are two types:

  • A single line comment is written after a double forward slash (//), e.g.
    // I am a comment
  • A multi-line comment is written between the strings /* and */, e.g.
    /*
      I am also
      a comment
    */

So for example, we could annotate our last demo's JavaScript with comments like so:

// Function: creates a new paragraph and appends it to the bottom of the HTML body.

function createParagraph() {
  let para = document.createElement('p');
  para.textContent = 'You clicked the button!';
  document.body.appendChild(para);
}

/*
  1. Get references to all the buttons on the page in an array format.
  2. Loop through all the buttons and add a click event listener to each one.

  When any button is pressed, the createParagraph() function will be run.
*/

const buttons = document.querySelectorAll('button');

for (let i = 0; i < buttons.length ; i++) {
  buttons[i].addEventListener('click', createParagraph);
}

Note: In general more comments is usually better than less, but you should be careful if you find yourself adding lots of comments to explain what variables are (your variable names perhaps should be more intuitive), or to explain very simple operations (maybe your code is overcomplicated).

Summary

So there you go, your first step into the world of JavaScript. We've begun with just theory, to start getting you used to why you'd use JavaScript and what kind of things you can do with it. Along the way, you saw a few code examples and learned how JavaScript fits in with the rest of the code on your website, amongst other things.

JavaScript may seem a bit daunting right now, but don't worry — in this course, we will take you through it in simple steps that will make sense going forward. In the next article, we will plunge straight into the practical, getting you to jump straight in and build your own JavaScript examples.

In this module