Đôi điều về Javascript

Đôi điều về Javascript đề cập đến vai trò của javascript trong phát triển ứng dụng web, lịch sử và các kiến thức quan trọng trong Javascript.

1. Giới thiệu về Javascript

JavaScript là ngôn ngữ lập trình được sử dụng để tạo các trang web tương tác ở phía client (trình duyệt). Ví dụ  hiện các thông báo quan trọng với người dùng,  hiển thị thông tin động theo ngữ cảnh, ẩn hiện nội dung, hoặc tính toán, xử lý dữ liệu… Cùng với HTML và CSS, Javascript là thành phần cốt lõi cho việc lập trình web ở phía client.

Javascript cũng được dùng để lập trình web ở phía server, giúp triển khai các chức năng, thực hiện các tác vụ quan trọng như tính toán , xử lý, lưu trữ dữ liệu ở phía server.

2. Lịch sử của Javascript

Năm 1995, hãng NetScape cho ra đời một ngôn ngữ đơn giản để giúp cho việc phát triển web được tiện lợi hơn. Từ đó Javascript hình thành, và đến năm 1997 trở thành chuẩn ECMA đầu tiên.

ECMAScript là tên chính thức của JS. Các phiên bản ECMAScript được viết tắt là ES1, ES2, ES3, ES5, ES6. Đến năm 2016 thì các phiên bản ES không được đặt tên theo thứ tự nữa mà là theo năm, như  ECMAScript 2016, 2017, 2018, 2019, 2020. Bảng sau liệt kê thứ tự các version ECMAScript , một số cập nhật mới trong từng phiên bản và link tham khảo:

VersionTên chính thứcMô tả
ES1ECMAScript 1 (1997)Version đầu tiên
ES2ECMAScript 2 (1998)
ES3ECMAScript 3 (1999)Bổ sung regular expression
Thêm cơ chế bắt lỗi try/catch
Có thêm cú pháp switch
Vòng lặp do-while
ES4ECMAScript 4Không có đưa ra release
ES5ECMAScript 5 (2009)


Thêm strict mode
Bổ sung JSON,  hàm string.trim()
Thêm hàm Array.isArray() và các hàm lặp qua array
Thêm định nghĩa đối tượng và mảng bằng  cách dùng dấy phầu y phân cách giữa các thuộc tính. https://www.w3schools.com/js/js_es5.asp   
ES6ECMAScript 2015


Thêm từ khóa let và const
Thêm giá trị mặc định cho các tham số
Thêm hàm  Array.find(), Array.findIndex() https://www.w3schools.com/js/js_es6.asp  
ECMAScript 2016

Thêm toán tử lũy thừa (**)
Thêm hàm Array.includes()
 https://www.w3schools.com/js/js_2016.asp  
ECMAScript 2017

Thêm các hàm string padding
Thêm các hàm Object.entries(),  Object.values()
Thêm các hàm async
https://www.w3schools.com/js/js_2017.asp  
ECMAScript 2018

Thêm các thuộc tính rest / spread
Thêm vòng lặp bất đồng bộ
Thêm  Promise.finally()
Thêm đối tượng RegExp
 https://www.w3schools.com/js/js_2018.asp  
ECMAScript 2019

Thêm hàm String.trimStart(), String.trimEnd()
Thêm hàm Array.flat()
Thêm hàm Object.fromEntries . Optional catch binding
 https://www.w3schools.com/js/js_2019.asp  
ECMAScript 2020

Thêm toán tử Nullish Coalescing (??)
 https://www.w3schools.com/js/js_2020.asp  

3. Javascript phía client

Javascript ra đời khi các nhà công nghệ cần có một ngôn ngữ chạy trong trình duyệt để việc tạo lập trang web được linh động và dễ dàng hơn. Từ đó Javascript có mặt và các version của javascript liên tục được nâng cấp, cải thiện.

Chính vì hoạt động trong trình duyệt, cho nên khả năng ứng dụng của Javascript là rất lớn. Nó giúp cho developer thực hiện các xử lý tính toán ở phía người dùng mà không cần thực thi nhiều ở phía server. Từ đó giúp tăng hiệu năng server, tăng tốc độ hoạt động của trang web. Điều này rất quan trọng khi thực hiện các dự án lớn, hoặc các dự án trong nội bộ doanh nghiệp (intranet), các dự án nhiều người dùng,  nghiệp vụ phức tạp, cần chia sẽ bớt tính toán về phía client.

Nhờ có Javascript được tích hợp trong trình duyệt mà trình duyệt đã trở thành một nền tảng để phát triển cho các ứng dụng web. Không cần phải training cho người sử dụng nhiều khi triển khai các dự án web vì trình duyệt ai cũng biết dùng. Cho nên đối với mọi lập trỉnh viên web, ai cũng phải cần đến Javascript để thực hiện các chức năng, bất kể lập trình front-end hay back-end.

4. Javascript phía server

Đến những năm 2000, Javascript bắt đầu được hiện thực trên phía máy chủ, gọi là Server-side JavaScript.  Trong máy chủ, JavaScript được triển khai để tương tác với các loại cơ sở dữ liệu, file system, Mail.

NodeJS ra đời nằm 2009 là nền tảng phổ biến nhất giúp triển khai JavaScript phía máy chủ (Bạn có thể xem danh sách các server side javascript tại đây: https://en.wikipedia.org/wiki/List_of_server-side_JavaScript_implementations

NodeJS từ khi ra đời đã phát triển rất nhanh chóng và mạnh mẽ. Ngày nay NodeJS là 1 lựa chọn quan trọng cho lập trình viên khi cần triển khai các dự án có tương tác cao từ phía các người dùng (mạng xã hội, chat, notification) , media stream (upload file, video, audio) , các ứng dụng thời gian thực…

Với sự ra đời của NodeJS, các lập trình viên am hiểu về Javascript phía client có thể vận dụng kiến thức đã có để lập trình luôn ở phía server.

5. Một số kiến thức quan trọng trong Javascript

a.  Xử lý mảng trong Javascript

Mảng (array) là 1 biến đặc biệt, mỗi 1 biến dạng mảng chứa nhiều giá trị để bạn xử lý.  Mỗi phần tử có thể thuộc nhiều kiểu khác nhau như  number, string, object … đều được Ví dụ mảng chứa các số, chuỗi, mảng chứa thông tin các quyển sách …

–  Tạo mảng trong Javascript

<script>
var hoa = [`Hồng`,`Lài`,`Sen`,'Mai',"Cúc"];
var diem = [8,9,7,6,10,5,4];
var d = [5 ,"Sỹ Thanh","2004-02-01", ['091812345', '038 123432']  ]; 
var listSach = [
    { id: 1, ten:"Mùi hương trầm", gia: 125000},
    { id: 2, ten:"Nói với tuổi 20", gia: 45000},
    { id: 3, ten:"Hiểu về trái tim", gia: 150000},
    { id: 4, ten:"Quẳng gánh lo đi", gia: 80000},
];
var htmlSP= [
    `<div class="sach"> 
        <h3>Tên sách: Mùi hương trầm </h3>
        <p>Giá : <i>125000 VNĐ</i> </p>
    </div>`,
    `<div class="sach"> 
        <h3>Tên sách: Nói với tuổi 20 </h3>
        <p>Giá : <i>45000 VNĐ</i> </p>
    </div>`,
    `<div class="sach"> 
        <h3>Tên sách: Hiểu về trái tim </h3>
        <p>Giá : <i>150000 VNĐ</i> </p>
    </div>`,
];
</script>

–  Thao tác trên mảng Javascript:

Khi đã có 1 mảng, bạn có thể thực hiện nhiều thao tác trên đó. Như tìm kiếm phần tử, trích xuất phần tử, thêm xóa phần tử, ghép phần tử, sắp xếp phần tử, lưu vào/ lấy ra từ locaStorage, sessionStorage…

<script>
//sắp tăng string 
hoa.sort(); //['Cúc', 'Hồng', 'Lài', 'Mai', 'Sen']

//sắp giảm string 
hoa.sort().reverse();//['Sen','Mai','Lài','Hồng','Cúc']

//sắp tăng number
diem.sort( (a,b)=> a-b ); //[4,5,6,7,8,9,10]

//sắp giảm number
diem.sort( (a,b)=> b-a ); //[10,9,8,7,6,5,4]
diem.sort((a, b) => (a > b ? -1 : 1))

//thêm phần tử vào cuối
hoa.push("Đào");

//thêm phần tử vào vị trí mong muốn
hoa.splice(3, 0, "Mận"); //chèn Mận vào vt 3, kô xóa pt nào
//['Sen','Mai','Lài','Mận','Hồng','Cúc','Đào']

//Xóa 1 phần tử từ vị trí 3
h = hoa.splice(3,1);
console.log(h); //['Mận']
console.log(hoa); // ['Sen', 'Mai', 'Lài', 'Hồng', 'Cúc', 'Đào']

//lấy và xóa phần tử cuối
var sp = hoa.pop();

sessionStorage.setItem("listSach", JSON.stringify(listSach));
var ls = JSON.parse( sessionStorage.getItem("listSach") );
</script>

–  Lặp qua mảng Javascript

Lặp qua mảng để tính toán, tìm kiếm phần tử, hoặc để tạo mảng mới dựa trên mảng đang có, hoặc để hiển thị mảng trong trang web…

<script>
    htmlSP.forEach( h =>{ 
        document.getElementById('kq').innerHTML+=h;
    });
    listSach.forEach( s =>{ 
        document.getElementById('kq').innerHTML+=`
        <p>Tên sách: ${s.ten} Giá: ${s.gia}
        `;
    });
    diem = diem.map(d => d+1);//tăng 1 cho từng phần tử
</script>

Qua các ví dụ trên, có thể khẳng định vấn đề xử lý mảng dữ liệu trong Javacript là rất quan trọng. Bởi vì Javascript là kỹ thuật lập trình ở đầu cuối phía client, các các mảng dữ liệu trong Javascript thường có từ nhiều nguồn khác nhau. Ví dụ từ việc nhập liệu của người dùng, hoặc từ tính toán mà ra, hoặc lấy trong sesstionStorage/localStorage, hoặc request từ ứng dụng khác, hoặc request từ server.

Khi đã có mảng, các mã lệnh Javascript sẽ thực hiện thêm bớt, trích xuất, tính toán, tìm kiếm, sắp xếp, hiển thị ra trang web. Do đó rất dễ hiểu khi Javascript có nhiều hàm xử lý trên mảng. Bạn có thể tìm hiểu thêm về mảng, tại các link sau:

b.  Xử lý chuỗi trong Javascript

Trong Javascript, xử lý chuỗi cũng là vấn để quan trọng. Vì dữ liệu cần xử lý trong trang đa phần là text (html, css, js).

Chuỗi thật ra cũng là mảng các ký tự, do đó các hàm xử lý trong mảng cũng có thể  áp dụng cho chuỗi.  Cộng thêm các hàm xử lý chuỗi đặc thù, kết quả là chúng ta có nhiều hàm xử lý chuỗi trong javacript có thể dùng.

Mời tham khảo các link sau về chuỗi và xử lý chuỗi trong Javascript:

c.  Xử lý ngày giờ trong Javascript

Xử lý ngày giờ là vấn đề luôn phải xử lý trong mọi dự án và trong Javascript cũng thế. Có nhiều hàm có sẵn trong Javascript giúp xử lý dữ liệu kiểu ngày giờ. Bạn có thể tham khảo các link sau

d.  Lập trình đối tượng trong Javascript

Đối tượng hiểu nôm na là các biến có cấu trúc. Mỗi biến có nhiều thuộc tính và nhiểu hàm. Mỗi thuộc tính có tên và giá trị, mỗi hàm có tên và code xử lý. Trong javascript, có thể tạo đối tượng theo nhiều cách khác nhau.

  • Cách 1: tạo đối tượng theo kiểu đơn giản ojbject literals
<script>
var hs1 = {
    ho:"Nguyễn Văn", ten: "Tèo",
    hoten:function() { this.ho + " " + this.ten}
}   

var ptb2= {};
ptb2.a=1; ptb2.b=3; ptb2.c=-1;
ptb2.delta= function() { 
 return this.b*this.b-4*this.a*this.c;
}
</script>
  • Cách 2: tạo đối tượng theo kiểu Object contructor function
<script>
function Khachhang(ht, dc, dt){
    this.hoten = ht;
    this.diachi = dc;
    this.dienthoai = dt;
    this.thongtin = function(){
        console.log(this.hoten , this.diachi, this.dienthoai);
    }
}
var k1 = new Khachhang("Lấp lánh", "tp Trăng Vàng", 09181234);
k1.tuoi = 50;
k1.thongtin(); //Lấp lánh tp Trăng Vàng 09181234
</script>
  • Cách 3: tạo đối tượng với Javasript class
<script>
class Sach {
    constructor(ten, gia, km) {
        this.tuasach = ten;
        this.gia = gia;
        this.km=km;
    }
    tien() {
        if (this.km==1) return this.gia*90/100;
        else return this.gia;
    }
}
let b1 = new Sach("Mùi hương trầm", 190000, 0);
</script>

Ngoài ra còn nhiều vấn đề khác liên trong OOP như các cách kế thừa, prototype, lặp qua object …Mời bạn tham khảo thêm ở các link sau:

e. Regular Expression

Regular Expression (biểu thức chính quy) – viết tắt là regexp – là một chuỗi diễn tả một mẫu ký tự dùng để so khớp với 1 chuỗi gốc. RexExp thường dùng trong các bài toán tìm kiếm và xử lý theo mẫu (trừu tượng) chứ không dựa vào những chuỗi ký tự cố định (rõ ràng), ví dụ:

  • So khớp các giá trị nhập trong form với mẫu cho trước (dùng khi validate form)
  • Tách chuỗi theo các mẫu cho trước
  • Tìm kiếm chuỗi con theo công thức nào đó (ví dụ tìm chuỗi có 3 ký tự bắt đầu bằng T)
  • Tìm và thay thế ký tự theo mẩu

Các link tham khảo để tìm hiểu thêm có thể xem ở đây:

f. Bất đồng bộ

Asynchronous (bất đồng bộ) tức là code chương trình không hẳn chạy tuần tự từ trên xuống nữa. Với kỹ thuật này, có những lệnh chạy hầu như cùng lúc. Có khi lệnh phía dưới cho kết quả trước cả lệnh phía trên.

Cái hay của xử lý bất đồng bộ là nó giúp tối ưu được sức mạnh của hệ thống, giúp giảm thời gian chờ, từ đó code chạy nhanh hơn.  Xem í dụ sau

<script>
    // ...
    thuchienNauCom();
    thuchienChienTrung();
    thuchienAnCom(); 
</script>

Với kỹ thuật tuần tự, nếu hàm thuchienNauCom() chạy khoảng 60 phút, hàm thuchienChienTrung() chạy 30 phút thì hàm thuchienAnCom() sẽ phải đợi 90 phút mới chạy , mất thời gian trong khi hệ thống còn rất rãnh.

Còn với kỹ thuật bất đồng bộ thì không cần mất thời gian nhiều như thế, hàm thuchiennauCom() và hàm thuchiencChienTrung() có thể thực hiện cùng lúc, giúp giảm thời gian thời gian chờ và tận dụng khả năng của hệ thống tốt hơn.

Còn điểm không tốt của bất đồng bộ?  Không phải hệ thống nào cũng dùng bất đồng bộ được, thứ hai là khó làm quen xử lý và kiểm soát lỗi phát sinh.

Ví dụ 1:

<script>
    setTimeout( () => {console.log("Đời đẹp lắm");} , 1000);    
    console.log("Em có biết không");
    /*Kết quả:
        Em có biết không
        Đời đẹp lắm
    */
</script>

Ví dụ 2:

<script>
url=`https://api.openweathermap.org/data/2.5/weather?id=1566083&appid=YOUR_API_key`;
fetch(url)
.then( res => res.json())
.then( data => console.log(data));
console.log("Lấy thời tiết ở HCM");
</script>

Trong ví dụ trên, lệnh console.log(“Lấy thời tiết ở HCM”); nằm ở sau cùng nhưng kết quả ở trước.

Liên quan đến lập trình bất đồng bộ, có 3 kỹ thuật được sử dụng, đó là callback, promise và async/await. Nói chung : kỹ thuật lập trình bất đồng bộ giúp tối ưu tốc độ của hệ thống,  giúp chạy nhanh hơn. Chi tiết mời xem thêm các link sau:

g.  Tạo request ajax

Trong mô hình web truyền thống, một request từ trình duyệt được gửi đến server khi xảy ra 1 trong 3 ngữ cảnh sau:

  1. User nhập URL của trang web trong thanh địa chỉ rồi enter.
  2. User nhắp một hyperlink trong trang.
  3. Khi user nhắp nút submit của 1 form.  

Trong 3 ngữ cảnh  này, dễ thấy là đều do user chủ động thực hiện(enter địa chỉ, nhắp link, submit form) .  Vậy 1 request có được tạo ra trong trường hợp nào nữa hay không? Có. Đó là khi lệnh fetch được chạy. Đây là lệnh javascript giúp tạo request đến web server để nhận thông tin.

Với lệnh fetch, lập trình viên có thể tạo request đến server dựa vào các sự kiện xảy ra trong trang như onclick, onblur, onsubmit, onkeyup…

Tạo 1 request ajax không làm trang web nạp lại, nó giúp lấy dữ liệu từ server để hiện trong trang. Hoặc nó giúp gửi yêu cầu lên server để thực hiện 1 việc gì đó, ví dụ như kiểm tra username, kiểm tra email, lấy thông tin user, lấy danh sách dữ liệu…

Ngoài cách dùng lệnh fetch để tạo request ajax, có thể dùng đối tượng XMLHttpRequest để tạo request cũng được, đây là đối tượng cũ xưa, dùng khó hơn lệnh fetch.

Cách dùng request ajax chi tiết hơn mời bạn xem ở các link sau:

h. Các vấn đề khác:

Trong javascript, còn nhiều vấn đề quan trọng khác như xử lý  sự kiện, errors, functions, loop, tương tác với DOM… mời xem thêm các link sau :

6.  Vài thư viện và framework javascript quan ttọng

Do Javascript rất quan trọng trong lập trình web ở phía client, cho nên nhiều thư viện javascript, javascript framework đã ra đời để giúp lập trình viên lập trình được nhanh và thuận lợi hơn. Có thể kể đến các thư viện như Jquery, lodash, moment, carbon, datatable và các framework như Angular, VueJS, Ember.js, Meteor, Backbone.js …

Đặc điểm chung của các thư viện là cung cấp thêm nhiều hàm mới, nhiều tiện ích mới giúp tính toán, xử lý, hiển thị dữ liệu dễ hơn. Các framework javascript còn can thiệp sâu hơn trong việc tạo các ứng dụng ảo (Angular), cung cấp nhiều chức năng nền như data binding, scope để lập trình viên dễ dàng triển khai các chức năng.

Chi tiết hơn mời bạn xem ở các link sau đây:

Trên đây là đôi điều về Javascript để bạn rewview. Bài viết dành cho các bạn đã biết sơ qua về Javascript để tìm hiểu thêm. (Còn tiếp)