Trở lại những ngày đầu của nền tảng Java, khi các nhà báo và thậm chí đôi khi các lập trình viên mới còn bị nhầm lẫn giữa ngôn ngữ JavaScriptJava. Cả hai ngôn ngữ đều phổ biến do tính ứng dụng của chúng cho việc lập trình web, cuối cùng và trong một vài năm sau, chúng đã ngang nhau về khả năng sáng tạo nổi tiếng. Ngày nay hầu hết mọi người đều phân biệt được hai ngôn ngữ này, nhưng với các nhà phát triển Java việc chế nhạo JavaScript là một ngôn ngữ đồ chơi, thậm chí không phù hợp cho việc tạo kịch bản lệnh vẫn còn phổ biến. Có điều là, JavaScript (giống như ngôn ngữ Java) vẫn sống và thậm chí còn phát triển. Nó là cơ sở của các kỹ thuật lập trình phía máy khách như Ajax và các nỗ lực phía máy chủ như Node.js và tầm quan trọng của nó đối với việc phát triển ứng dụng di động đang bắt đầu nổi lên. Nó cũng là ngôn ngữ được mã Java biên dịch sang trong Bộ công cụ web nổi tiếng của Google – GWT – Google Web Toolkit.

Trong bài này, tôi sẽ giải thích tại sao JavaScript lại quan trọng với các nhà phát triển Java hiện nay và xem qua một số cú pháp JavaScript có ích nhất, giải thích nó khác với ngôn ngữ Java như thế nào và cũng so sánh nó với các ngôn ngữ động hiện đại hơn như Groovy và Ruby.

Bối cảnh phát triển Java đã thay đổi hoàn toàn kể từ khi công nghệ Java đã xuất hiện lần đầu tiên. Nhờ các khung công tác nguồn mở hoàn thiện và cơ sở hạ tầng triển khai cho thuê tin cậy mà ngày nay chúng ta có thể lắp ráp, thử nghiệm, chạy và duy trì các ứng dụng Java một cách nhanh chóng và không tốn kém. Trong loạt bài này, Andrew Glover khám phá một loạt các công nghệ và các công cụ làm cho hình mẫu phát triển Java mới này trở nên khả thi.

Tại sao JavaScript lại trở nên quan trọng

JavaScript được Netscape giới thiệu vào năm 1995 và nó nhanh chóng được công chúng yêu thích. Lý do có liên quan nhiều đến sự xuất hiện của các trang web như là một nền tảng môi trường truyền thông thương mại: Với JavaScript, bạn có thể tác động đến hành vi của trang web trong trình duyệt bằng lập trình. Chỉ điều đó thôi cũng đã thú vị rồi! Việc xác nhận hợp lệ của dạng HTML và mánh khóe hình ảnh hạn chế đã là vấn đề quan trọng hàng đầu.

Kể từ đó, JavaScript đã trải qua một vài thay đổi. Vào lúc đó Netscape đã có một sản phẩm là Netscape Application Server (Máy chủ ứng dụng Netscape), dựa trên JavaScript phía máy chủ để xây dựng các ứng dụng web. Vài năm sau đó, sự ra đời của Ajax và các thư viện tiện ích như JQuery, Prototype và ExtJS đã tiếp tục châm ngòi cho các mối quan tâm về JavaScript. Gần đây hơn, JavaScript phía máy chủ đã trở lại với Node.js, một framework I/O dựa trên sự kiện dùng để xây dựng các ứng dụng web phía máy chủ bằng cách sử dụng công cụ V8 JavaScript của Google.

Để chăm lo cho tương lai của sản phẩm của mình, Netscape đã gửi JavaScript lên tổ chức quốc tế về tiêu chuẩn hóa Ecma. Đó là lý do tại sao một số người gọi JavaScript là ECMAScript. Quan trọng hơn, đó là lý do tại sao hầu hết các trình duyệt web đều hỗ trợ ECMAScript. Kết quả là, các ứng dụng web gặp khó khăn đều không sử dụng JavaScript ở đâu đó và JavaScript dường như không thể thay đổi được điều đó. Hiện tại chưa có ngôn ngữ tạo kịch bản lệnh nào khác tương thích trình duyệt xuất hiện.

Ngày nay, mặc dù tiếng xấu của nó vẫn còn sót lại, nhưng JavaScript được cho là một trong những ngôn ngữ được sử dụng nhiều nhất (và có ích) trên hành tinh. Nếu bạn là một lập trình viên Java (hoặc một lập trình viên Ruby, Python hay PHP), có thể là bạn hoặc đã sử dụng JavaScript hoặc bạn sẽ sử dụng trong tương lai không xa. Việc hiểu biết một số tính năng của JavaScript có thể giúp bạn xây dựng các ứng dụng web phổ biến hơn tiếp theo. Hơn nữa, nó sẽ cho phép bạn sử dụng Node.js và thậm chí mở mang hiểu biết của bạn về những gì đang xảy ra trong lúc triển khai bên dưới một sản phẩm trong GWT.

Học lập trình javascript trực tuyến

Trong các phần tiếp theo, tôi sẽ tập trung vào các phần tử chính của cú pháp JavaScript, nêu bật các chuyến đi và các chỗ rẽ nhỏ đặc biệt có thể gây ngạc nhiên hoặc thích thú cho các nhà phát triển Java. Tuy nhiên, đầu tiên, tôi muốn xua tan một trong những lầm tưởng phổ biến về JavaScript: đó là bạn cần một trang web để tương tác với JavaScript.

Sử dụng JavaScript trong Chrome

Về mặt lịch sử, để chạy được JavaScript, nó đòi hỏi phải có một trình duyệt và một trang web gián tiếp. Đối với một số nhà phát triển điều đó đã gây ra phiền toái và thậm chí trở ngại. May mắn thay, các trình duyệt đã phát triển; ngày nay cả Firefox lẫn Chrome đều cung cấp các IDE để chạy JavaScript.

Tôi thích giao diện điều khiển JavaScript tiện lợi của Chrome để theo đuổi ngôn ngữ này. Giống như trình shell của Python hoặc IRB của Ruby, Chrome cung cấp một môi trường tương tác để tìm hiểu JavaScript mà không cần dùng một trang web nào.

CoffeeScript

Nếu bạn thích những gì JavaScript có thể làm nhưng không thích cú pháp của nó, bạn nên xem xét CoffeeScript. CoffeeScript là “ngôn ngữ nhỏ bé dùng để biên dịch thành JavaScript” — có nghĩa là, CoffeeScript làm cho việc lập trình JavaScript trở nên dễ dàng hơn bằng cách nới lỏng một số cú pháp của nó. Về nhiều mặt, CoffeeScript có cảm giác giống nhiều hơn với Ruby hay Python nhưng lại tạo ra một sự tương đương một-một với JavaScript. Xem phần Tài nguyên để tìm hiểu thêm về CoffeeScript.

Để bắt đầu với giao diện điều khiển JavaScript của Chrome, bạn cần tải về bản Chrome phù hợp với hệ điều hành bạn đang dùng. Tiếp theo, mở một tab mới và chọn View > Developer > JavaScript Console (giao diện lập trình JavaScript). Ở dưới cùng của cửa sổ Chrome của mình, bạn sẽ thấy giao diện lập trình của nhà phát triển JavaScript hiện ra. Bạn có thể làm cho cửa sổ này trở thành một hộp thoại độc lập bằng cách chọn biểu tượng Undock ở góc dưới cùng bên trái của giao diện bàn điều khiển. Sau đó, bạn có thể chọn biểu tượng Console ở góc trên bên phải của hộp thoại để nhận được một cửa sổ rỗng đơn giản dùng cho việc tương tác với JavaScript, như thể hiện trong Hình 1:

Hình 1. Tương tác với JavaScript trong Google Chrome

lập trình web cơ bản đến nâng cao

Bây giờ chúng ta hãy xem xét một số cú pháp.

Các biến JavaScript

JavaScript là một ngôn ngữ khá dễ chịu, ở chỗ nó cho phép bạn tạo ra một vài lỗi lập trình và vẫn tải trang web. Các phần tử JavaScript thường hỏng thầm lặng, chủ yếu đó là các tin tức tốt lành. Trang Web ban đầu sẽ vẫn còn thô nếu việc lập trình JavaScript cẩu thả cấm các trang được load. Điều đó nói rằng, khi chúng ta dựa vào JavaScript để làm những điều khác thường hơn (như việc cập nhật trạng thái trang không đồng bộ), việc tạo mã JavaScrip không cẩn thận sẽ gây ra nhiều vấn đề. Vì lý do này mà các nhà phát triển Java nên dành thời gian để hiểu một số khía cạnh nhất định về cú pháp của JavaScript.
Việc xử lý các biến của JavaScript đặc biệt quan trọng và cần hiểu rõ. Ví dụ, bạn có thể định nghĩa một biến có tên là foo chẳng hạn hoặc trực tiếp hoặc thông qua việc khai báo var, như trong Liệt kê 1:

Liệt kê 1. Biến foo

foo = 'foo'
var bar = 'bar'

Biến foo trong Liệt kê 1 là một biến hợp lệ trong JavaScript. Nhưng vì nó thiếu một khai báo var, nên nó là một biến toàn cục. Do đó cần xem xét cẩn thận các biến được định nghĩa với var (ví dụ, trong hàm có định nghĩa các biến trong đó).

Nói chung, không nên dùng các biến toàn cục. Vì chúng có thể dễ dàng được truy cập và thay đổi ở bất cứ đâu trong ứng dụng JavaScript, nên việc sử dụng chúng có thể dẫn đến lỗi mà ta không hay biết. Vì vậy, khi bạn lập trình JavaScript, đừng quên var trong các biến của mình.

Các kiểu nguyên thủy và các đối tượng

Trong khi JavaScript không đơn giản, thì nó lại khá đơn giản khi nói đến các kiểu. Trong thực tế, JavaScript thực sự chỉ có bốn kiểu cơ bản, ba trong số đó là các kiểu nguyên thủy. Các kiểu nguyên thủy của JavaScript là Number, String và Boolean. Bạn có thể xem thông tin các kiểu này thông qua toán tử typeof tiện dụng của JavaScript.

Hãy cùng dùng thử toán tử này. Trong giao diện lập trình JavaScript của Chrome, hãy gõ đoạn mã trong Liệt kê 2:

Liệt kê 2. Kích hoạt các kiểu

var string = "test"
typeof string

Bạn sẽ thấy giao diện bàn điều khiển in ra giá trị “string.” Bạn cũng lưu ý rằng các dấu chấm phẩy là tùy chọn trong JavaScript. Giống như hầu hết các ngôn ngữ phổ biến, một string được mô tả bằng các dấu nháy; cho nên, các số được mô tả bằng các số. Các kiểu Boolean được mô tả bằng các giá trị true (đúng) hay false (sai), không có các dấu nháy.

Liệt kê 3. Các số và chân lý của JavaScript

var aNumber = 10
var anotherNumber = 0.99
var aBool = true
var notABoolean = "false"

Bạn sẽ lưu ý rằng JavaScript không phân biệt giữa các kiểu số; các số chỉ là các số, theo các định dạng khác nhau.
JavaScript cũng hỗ trợ các đối tượng tổng quát có các kiểu cá thể trong và chính bản thân các đối tượng này, chẳng hạn như Array, như trong Liệt kê 4:

Liệt kê 4. Một cá thể Array

> var myArray = ["Hello", 1, true]
> typeof myArray
"object"
> myArray instanceof Array
true

Các Array (Mảng) trong JavaScript rất thích các danh sách theo các ngôn ngữ khác: người ta có thể tạo ra chúng với kích cỡ tùy ý và có thể chứa bất cứ thứ gì mà bạn muốn đưa vào các mảng đó. Giống như trong Ruby hoặc Groovy, có thể tạo ra các Array của JavaScript bằng một cú pháp bằng chữ: []. Hơn nữa, các Array của JavaScript hỗ trợ các phương thức (được hiển thị trong Liệt kê 5) được bạn dự kiến trong các ngôn ngữ khác có hỗ trợ các danh sách:

Liệt kê 5. Các phương thức của Array

> var myArray = ["Hello", 1, true]
> myArray[0]
"Hello"
> myArray.length
3
> myArray.pop()
true
> myArray
["Hello", 1]
> myArray.pop()
1
> myArray
["Hello"]
> myArray.push("pushed")
2
> myArray
["Hello", "pushed"
]

Bạn có thể nhận được một giá trị của Array thông qua vị trí của nó, bắt đầu từ số không. Các Array đáp lại với push và pop, ở đây push thêm một mục (vào vị trí cuối cùng trong danh sách của nó) và pop loại bỏ một mục (giống như một ngăn xếp, ra khỏi vị trí cuối cùng).
Các Array cũng hỗ trợ việc lặp lại, được hiển thị trong Liệt kê 6:

Liệt kê 6. Lặp lại qua một Array

> var myArray = [1,2]
> for(var i = 0; i < myArray.length; i++) { console.log(myArray[i]) }
1
2

Ép kiểu

JavaScript không chỉ là một ngôn ngữ định kiểu yếu — nó thậm chí còn yếu hơn so với Ruby hoặc Groovy! JavaScript cố ép kiểu các đối tượng thành bất cứ kiểu nào có ý nghĩa tại một điểm đã cho trong đoạn mã. Điều đó có ý nghĩa trong bối cảnh ban đầu người ta đã phát minh ra JavaScript: tương tác trang web. Mã JavaScript viết cẩu thả không nên cấm một ai đó đọc một bài báo trực tuyến!

Ép kiểu không phải là duy nhất với JavaScript, nhưng kiểu riêng của JavaScript là khá linh hoạt. Điều này có thể là một điều tốt hay điều xấu tùy thuộc vào quan điểm của bạn. Sự không chặt chẽ của JavaScript có thể ẩn giấu các lỗi, giống như các biến toàn cầu đã có.

Ví dụ, tôi có thể định nghĩa một Array và sau đó vô tình cố làm một cái gì đó bằng số với nó hoặc thậm chí một số móc nối String, như trong Liệt kê 7:

Liệt kê 7. Tính linh hoạt về kiểu của JavaScript

> var myArray = [1,2]
> console.log(2 * myArray)
> console.log("A" + myArray)

Trong trường hợp này, thông báo log đầu tiên sẽ in ra NaN, trong khi thông báo thứ hai sẽ in ra A1,2. Trong cả hai trường hợp, mã “đã làm việc” như không có lỗi gì cả — JavaScript chỉ cần tiếp tục truyền tải. Đây là việc định kiểu yếu tại điểm cực trị của nó. Mã tương tự trong Ruby sẽ không làm việc như vậy, như trong Liệt kê 8:

Liệt kê 8. Ruby không làm theo cách đó

> array = ["A", "B"]
> ans = 2 * array

Mã Ruby trong Liệt kê 8 sẽ báo lỗi là:

TypeError: Array
can't be coerced into Fixnum

Và nếu tôi cố gắng thêm “A” vào array, nó sẽ tạo ra:

TypeError: can't convert
Array into String

Nếu tôi đã dùng thử thủ thuật tương tự trong Groovy, tôi sẽ nhận được kết quả đại loại như:

groovy.lang.MissingMethodException: No signature of method: 
java.lang.Integer.plus() is applicable for argument types: (java.util.ArrayList) values:
[[A, B]]

Vì vậy, bạn có thể thấy các mức định kiểu yếu khác nhau trong hành động. Rõ ràng, nếu có một thước đo về tình trạng yếu kém về kiểu, JavaScript sẽ là yếu nhất trong tất cả các ngôn ngữ đó!

Các hàm JavaScript

Một hàm JavaScript, giống như một phương thức Java, là một cấu kiện để định nghĩa và đóng gói hành vi sử dụng lại. Các hàm trong JavaScript thoạt nhìn và cảm nhận rất giống như các bao đóng của Groovy. Các hàm trong JavaScript là các đối tượng. Trong thực tế, chúng là đối tượng hạng nhất, rất khác các phương thức trong mã Java. Vì các hàm JavaScript là các đối tượng, nên chúng có thể được chuyển sang các hàm khác và có thể được gọi tùy ý.

Các hàm được định nghĩa bằng từ khóa function (hàm). Bạn có thể chỉ rõ các đối số như bạn muốn trong một khai báo phương thức theo ngôn ngữ Java, thêm nữa bạn có thể trả về một cái gì đó từ một hàm JavaScript. Không giống như các ngôn ngữ động, như Groovy hoặc Ruby, ở đây một cuộc gọi trả về là tùy chọn (và do đó dòng cuối cùng của bất kỳ phương thức nào đều được trả về), các hàm trong JavaScript phải sử dụng một câu lệnh return nếu chúng muốn trả về một cái gì đó; nếu không, chúng chẳng trả về cái gì cả.
Bạn gọi các hàm trong JavaScript như bạn vẫn gọi các bao đóng trong Groovy. Trong Liệt kê 9, tôi định nghĩa một hàm đơn giản, không có tham số nào. Mục đích của hàm này là in “blah” ra giao diện bàn lập trình JavaScript trong Chrome.

Liệt kê 9. Định nghĩa và gọi một hàm theo JavaScript

> function blah() { console.log("blah"); }
> blah() //prints blah
> blah.call() //prints blah
> blah.apply() //prints blah

Bạn có thể gọi một hàm trực tiếp bằng các dấu ngoặc đơn (đó là, ()), qua phương thức call (gọi) hoặc qua phương thức apply (áp dụng). Trạng thái hạng nhất của các đối tượng hàm được trình bày rõ ở đây. Liệt kê 10 cho thấy điều gì sẽ xảy ra khi tôi cố gắng gọi một phương thức sai dựa vào hàm blah:

Liệt kê 10. Các hàm như là các đối tượng trong JavaScript

> blah.foo()

Trong trường hợp này, bạn sẽ thấy một thông báo lỗi nói rằng rằng foo không phải là một phương thức đã định nghĩa, như sau:

TypeError: Object function blah() { console.log("blah"); } has no method 'foo'

Bây giờ hãy đọc lại thông báo lỗi đó. Nó nói rằng foo chưa được định nghĩa, điều đó ngụ ý rằng nếu nó đã được định nghĩa thì mọi thứ đã phải hoạt động được rồi.

Các lớp trong JavaScript

JavaScript hỗ trợ các kiểu nguyên thủy, mà tôi đã thảo luận. Nó cũng hỗ trợ các đối tượng, như Array. JavaScript không hỗ trợ các lớp — ít nhất là không phải theo nghĩa của ngôn ngữ Java cổ điển. Vì JavaScript là một ngôn ngữ dựa trên nguyên mẫu, bạn không định nghĩa các lớp: thay vào đó, hành vi được sử dụng lại thông qua việc nhân bản các đối tượng hiện có. Như vậy, trong JavaScript, bạn không định nghĩa các đối tượng lớp, bạn định nghĩa chúng trong các hàm, sau đó sử dụng các hàm lồng nhau để định nghĩa hành vi — đại loại bạn đã thấy trong hành động.

Để mô phỏng một lớp, bạn định nghĩa một hàm. Bạn có thể đặt cho nó một tên (đó là, một tên lớp), chỉ rõ các tham số (như trong một hàm tạo) và thậm chí sử dụng từ khóa .this, về cơ bản nó có nghĩa là tham khảo một biến trong phạm vi của hàm đó. Hơn nữa có thể đặt bí danh cho các hàm bên trong để trông giống như các cuộc gọi phương thức.
Để chứng minh, trong Liệt kê 11, tôi sẽ tạo ra một nguyên mẫu Message (còn được gọi là một lớp) siêu đơn giản. Tôi sẽ cung cấp một vài tham số (thông báo từ ai và thông báo gửi tới ai và thông báo thực tế) và lớp sẽ đại diện cho thông báo của tôi là JSON.

Liệt kê 11. Các hàm như là các lớp trong JavaScript

function Message(to, from, msg){
 this.to = to;
 this.from = from;
 this.msg = msg;

 this.asJSON = function(){
  return "{'to':'" + this.to + "', 'from':'" + this.from + "', 'message':'" +
    this.msg + "'}";
 }
}

Trong Liệt kê 11, tôi đã định nghĩa một hàm Message — một đối tượng có một tên và một vài thuộc tính; cụ thể là to, from và msg. Sau đó tôi đã định nghĩa một thuộc tính (asJSON) trỏ đến một hàm bên trong với công việc của hàm là chèn thủ công một đại diện chuỗi của thông báo JSON của tôi.
Lưu ý rằng tôi cũng có thể định nghĩa “lớp” này trong một trang web, tải nó bằng Chrome, mở giao diện bàn điều khiển JavaScript và sử dụng nó theo tương tác. Đó là những gì đang xảy ra trong Liệt kê 12:

Liệt kê 12. Sử dụng các lớp trong JavaScript

> var message = new Message('Andy', 'Joe', 'Party tonight!');
> message.asJSON();
"{'to':'Andy', 'from':'Joe', 'message':'Party tonight!'}"

Bạn có thấy hầu như mã này trông giống như mã Groovy hoặc thậm chí mã Java (nếu không có var) không? Thực tế là, hoàn toàn có thể sử dụng các kỹ thuật lập trình hướng đối tượng (OOP) để xây dựng các ứng dụng JavaScript (có nghĩa là, các chương trình chứa các đối tượng có dữ liệu và các phương thức tương tác với nhau).

Kết luận

Tôi hy vọng bài này đã đã phá tan ý kiến lỗi thời về việc nghĩ JavaScript là một ngôn ngữ đồ chơi. Trong thực tế JavaScript khá mạnh và có rất nhiều thú vị về cú pháp và sự dễ dàng của các ngôn ngữ mới hơn như Groovy và Ruby. Một số trong rất nhiều phẩm chất làm cho JavaScript bị nghi ngờ trong thập niên 90 được coi là hấp dẫn hiện nay.
Căn cứ vào tầm quan trọng của web với việc phát triển của ứng dụng Java và JavaScript chiếm giữ vị trí duy nhất là một ngôn ngữ tương thích với trình duyệt, mọi lập trình viên Java nên thành thạo về JavaScript — mang tính thời đại. Trình duyệt (dù có trên một máy tính hay trên thiết bị, điện thoại hoặc máy tính bảng di động) là phương tiện mà càng ngày càng có nhiều người tương tác với các ứng dụng. JavaScript là môi trường chung giữa tất cả các ngôn ngữ phía máy chủ. Ngoài ra, hiểu biết một số tính năng của JavaScript sẽ giúp cho bạn trở thành một lập trình viên tốt hơn trong bất cứ ngôn ngữ nào, bao gồm cả một ngôn ngữ mà bạn gọi là ngôn ngữ chính.

http://www.ibm.com/developerworks/vn/library/java/2013Q1/j-javadev2-18/index.html