Javascript Object dưới con mắt của Java Developer
Một trong những thách thức lớn nhất đối với Java developer khi tìm hiểu và áp dụng Javascript chính là sự khác biệt giữa việc cách giải thích khác nhau về object giữa hai ngôn ngữ. Nhìn qua thì Javascript có syntax khá tương tự Java, nhưng về cách tiếp cận lập trình hướng đối tượng của ...
Một trong những thách thức lớn nhất đối với Java developer khi tìm hiểu và áp dụng Javascript chính là sự khác biệt giữa việc cách giải thích khác nhau về object giữa hai ngôn ngữ.
Nhìn qua thì Javascript có syntax khá tương tự Java, nhưng về cách tiếp cận lập trình hướng đối tượng của Javascript với prototype-based thì vô cùng khác biệt so với class-based của Java.
Trong bài này, tôi sẽ trình bày về Javascript object dưới góc nhìn của một Java developer, và đưa ra một vài tip cũng như chiến thuật để Java developer có thể sử dụng tốt hơn, cũng như liên kết được concept lập trình hướng đối tượng trong Java và Javascript.
Trong khi Java và một số các ngôn ngữ lập trình khác có một loạt các datatype cũng như collection type thì Javascript chỉ có một số ít primitive type như Boolean, Number, String, Null và Undefined, một loại tương tự collection type là Array, và hỗ trợ các Javascript object khác. Đương nhiên điều này khiến việc học Javascript trở nên đơn giản hơn, nhưng cũng có nghĩa là trong những chức năng cụ thể, chúng ta phải implement những type hay collection mà những ngôn ngữ khác có thể đã cung cấp sẵn.
Bây giờ chúng ta đi vào vấn đề chính, đối với object thì việc đầu tiên là khởi tạo.
Khởi tạo Javascript object.
Có rất nhiều cách để khởi tạo Javascript object. Nhưng dưới con mắt của một Java developer, thông thường sẽ ưa thích việc khởi tạo object bằng cách sử dụng constructor. Một trong những lợi thế đặc biệt quan trọng của việc sử dụng phương thức này đó là object được tạo ra có thể sử dụng bằng nhiều constructor khác nhau, tương ứng với những mục đích khác nhau. Mặt khác, cách thức này cũng là cách thức gần gũi với Java cũng như các ngôn ngữ class-based nhất.
function Person(lastName, firstName) { this.firstName = firstName; this.lastName = lastName; } var person = new Person('Hoang', 'Nguyen'); console.log('The person is ' + person);
Phía trên là cách khởi tạo object bằng phương thức sử dụng constructor, ngoài ra trong Javascript còn có một cách khởi tạo object khác bằng việc sử dụng object initializer.
var person = {} person.firstName = 'Hoang'; person.lastName = 'Nguyen'; console.log('The person is ' + person);
Phương thức này là phương thức sử dụng một lần duy nhất bởi vì không có function nào được khai báo trước cho việc khởi tạo. Cũng như syntax của nó vô cùng khác biệt so với Java.
Và khi chạy hai đoạn code trên ta được kết quả như sau.
This person is [object Object] This person is [object Object]
Thêm hàm toString() vào Javascript object.
Tại sao lại là toString()? Tất cả các object trong Java đều được kế thừa từ Object class, toString là một phương thức mà object nào cũng có.
Cũng như Java, tất cả các object trong Javascript đều được extend từ một common object được gọi là Object, và đặc biệt các object tất cả đều được thừa kế những thuộc tính của Object.prototype.
Trong trường hợp này, Object.prototype.toString() cung cấp một chuỗi để đại diện cho tất cả các Javascript object. Trong kết quả ở trên, kết quả hiển thị là dạng ngắn gọn nhất, việc này tương tự với giá trị trả về mặc định của hàm toString() trong Java.
Cũng như việc người ta có thể override hàm toString() trong Java để kết quả trả về những thứ hữu ích hơn, phương thức khởi tạo object bằng constructor trong Javascript cho phép chúng ta có thể override hàm Object.prototype.toString(). Dưới đây là đoạn code cụ thể cho việc đó.
function Person(lastName, firstName) { this.firstName = firstName; this.lastName = lastName; } Person.prototype.toString = function personToString() { return this.firstName + ' ' + this.lastName; } var person = new Person('Hoang', 'Nguyen'); console.log('The person is ' + person);
Kết quả trả về bây giờ có ích hơn hẳn.
This person is Hoang Nguyen
Từ đó các bạn có thể thấy sự tương đồng giữa java.lang.Object trong Java và Object.prototype trong Javascript.
Tránh sử dụng với global scope trong Javascript
Javascript làm cho việc sử dụng biến ở global scope vô cũng dễ dàng. Các biến trong Javascript function được giới hạn trong function scope mà nó được khai báo bằng từ khóa var. Ngược lại các biến được khai báo mà không nằm trong bất cứ function nào thì không bị giới hạn gì cả và vì thế mỗi thay đổi tác động lên biến đó đều ảnh hưởng lên tất cả các function sử dụng nó. Ý tưởng này trong Javascript làm cho hầu như tất cả các Java developer muốn phát điên.
Từ khóa this thì lại là một sự ngạc nhiên đầy phức tạp khác từ Javascript bởi vì bản thân nó phụ thuộc rất nhiều vào việc nó được sử dụng như thế nào, nó được gọi ở đâu, và nó có nằm trong strict mode hay không. Nói cách khác, việc sử dụng this trong Javascript khó hơn nhiều so với Java, vì trong Java đơn giản là nó reference đến một instance cụ thể của class. Tuy nhiên, khi mà function trong Javascript được sử dụng như là một constructor (với từ khóa new) thì từ khóa this sẽ được bound bằng object đang được tạo ra, đó là lý do vì sao trong function constructor phí trên tôi sử dụng this.
Javascript object hao hao giống như Java Map.
Nhìn qua ví dụ đơn giản dưới đây về cách khai báo một object trong Javascript.
var superhero = {}; superhero.name = 'Superman'; superhero.strength = 100;
Đối với Java Map.
Map<String, Object> superhero = new HashMap<>(); superhero.put("name","Superman"); superhero.put("strength", 100);
Rõ ràng là có một sự tương đồng đúng không nào.
Tóm lại.
Mặc dù có những điểm chung về cú pháp, ngay cả cái tên cũng có chung tới bốn chữ cái, nhưng Java và Javascript lại rất khác nhau ở nhiều điểm. Trong thực tế, trong khi cả hai có thể đều được nói là object-oriented hay object-based, nhưng các ứng xử đối với việc tạo object trong mỗi ngôn ngữ lại khác nhau, một bên là class-based (Java) còn bên kia là prototype-based (Javascript).
Việc hiểu một số sự tương đồng cơ bản cũng như sự khác biệt của hai ngôn ngữ có thể giúp developer dễ dàng thay đổi qua lại giữa hai ngôn ngữ. Mặt khác trong ECMAScript 6 (ES6) cũng đã hộ trợ classes với các keyword class, constructor, extend để tạo sự tương đồng, hỗ trợ những developer sử dụng những ngôn ngữ object-oriented khác dễ tiếp cận hơn.
Bài gốc: https://codeaholicguy.wordpress.com/2015/12/22/javascript-object-duoi-con-mat-cua-java-developer/