* Login   * Register


Last visit was:
It is currently Tue Feb 20, 2018 10:52 pm
View unanswered posts
View active topics





Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Một số kỹ thuật hướng đối tượng làm nền tảng cho các Javascr
PostPosted: Sun May 31, 2009 1:51 pm 
Offline

Joined: Thu Feb 05, 2009 11:43 am
Posts: 11
---------
Một số kỹ thuật hướng đối tượng làm nền tảng cho các Javascript framework
Để đọc bài viết này, bạn cần có các kiến thức cơ bản về DOM và Javascript, đặc biệt là phần hướng đối tượng trong Javascript.
Nếu bạn là 1 web developer, bạn hẳn đã dùng Javascript trong các trang web của mình, chủ yếu để làm chất keo gắn kết các thành phần của giao diện. Tuy nhiên, Javascript còn có nhiều tính năng hướng đối tượng hơn bạn biết. Việc các trình duyệt bắt đầu hỗ trợ các bộ chức năng ngày càng chuẩn của Javascript và DOM đã mở ra khả năng viết các đoạn code phức tạp và hữu dụng hơn để chạy trên máy khách. Điều đó đã tạo nên hiện tượng AJAX.

Khi bắt đầu học cách viết các ứng dụng mang đậm tính AJAX, ta sẽ nhận thấy Javascript mà ta đã từng biết chỉ là phần nhỏ của tảng băng trôi. Javascript giờ đây được sử dụng không chỉ để phục vụ cho vài nhiệm vụ lặt vặt của giao diện như kiếm định thông tin nhập, mà đã trở nên cao cấp và phân lớp hơn rất nhiều, như một ứng dụng desktop thực sự. Ta có thể thấy các thư viện lớp, mô hình đối tượng, hệ thống phân cấp, các kiểu mẫu, và rất nhiều thứ khác mà ta chỉ thấy trong các code phía máy chủ. Chúng ta sẽ cần nâng cao kỹ năng Javascript của mình nhiều hơn nữa để viết được các ứng dụng kiểu mới. Nếu bạn muốn sử dụng các bộ thư viện Javascript như Prototype.js, Scriptaculous, moo.fx, Behaviour, YUI,..., rốt cuộc bạn sẽ vẫn phải đọc các code JS. Có thể do bạn muốn tìm hiểu họ làm như thế nào, bạn tò mò ưa khám phá, hoặc thông thường bởi đó là cách duy nhất giúp bạn biết làm thế nào để sử dụng chúng, vì tài liệu hướng dẫn dường như không được quan tâm đúng mức với hầu hết các bộ thư viện trên. Dù lý do là gì thì bạn cũng sẽ đối mặt với một số kỹ thuật khá xa lạ và... rùng rợn nếu chưa từng được biết tới những thứ gì tương tự.

Mục đích của bài viết này là giải thích chính xác các kiểu cấu trúc mà đa số chúng ta còn xa lạ.

1. JSON

JavaScript Object Notation (JSON) là một trong những từ được nhắc đến nhiều trong AJAX. JSON, nói nôm na là một cách thức khai báo đối tượng trong Javascript. VD:

Code:

var myPet = {
color: 'black',
legCount: 4,
communicate: function(repeatCount){
for(i=0;i<repeatCount;i++)
alert('Woof!');
}
};


Ở đây, ta tạo tham chiếu tới một đối tượng với 2 thuộc tính (color và legCount) và 1 phương thức (communicate). Mỗi thành phần của đối tượng được thể hiện bởi tên, theo sau bởi dấu : và sau đó là định nghĩa. Thuộc tính được gán giá trị, còn phương thức được gán một hàm ẩn danh (anonymous). Sau khi đối tượng được tạo và gán cho biến myPet, ta có thể sử dụng nó như sau:

Code:

alert('my pet is ' + myPet.color);
alert('my pet has ' + myPet.legCount + ' legs');
//if you are a dog, bark three times:
myPet.communicate(3);


Bạn sẽ thấy JSON được sử dụng rất nhiều trong JS: làm đối số cho hàm, giá trị trả về, server response, v.v...

2. Hàm cũng là... đối tượng!

Nghe không được bình thường cho lắm, nhưng trong JS hàm cũng là đối tượng. Bạn có thể truyền hàm chạy lòng vòng như đối số tới hàm khác như bạn truyền một đối số thông thường (VD: chuỗi) vậy. Việc này được sử dụng rộng rãi và rất thuận tiện. VD:

Code:

var myDog = {
bark: function(){
alert('Woof!');
}
};

var myCat = {
meow: function(){
alert('I am a lazy cat. I will not meow for you.');
}
};

function annoyThePet(petFunction){
//let's see what the pet can do
petFunction();
}

//annoy the dog:
annoyThePet(myDog.bark);
//annoy the cat:
annoyThePet(myCat.meow);


Chú ý rằng, ta truyền myDog.bark và myCat.meow mà không có cặp dấu (). Nếu có (), đó sẽ không phải là truyền hàm, mà là lời gọi phương thức và truyền giá trị trả về, giá trị này là undefined trong cả 2 trường hợp chó và mèo.

Và nếu bạn muốn con mèo lười kia... sủa, bạn có thể dễ dàng làm như sau:

Code:

myCat.meow = myDog.bark;
myCat.meow(); //alerts 'Woof!'

3. Mảng, phần tử và thành phần của đối tượng

2 dòng code JS sau thực hiện cùng 1 công việc:

Code:

var a = new Array();
var b = [];


Như đã biết, ta có thể truy nhập vào từng phần tử của mảng bởi []:

Code:

var a = ['first', 'second', 'third'];
var v1 = a[0];
var v2 = a[1];
var v3 = a[2];


Ngoài chỉ số, ta còn có thể truy nhập vào từng thành phần của đối tượng bởi tên của chúng. VD dưới tạo một đối tượng rỗng, sau đó nó được đưa thêm các thành phần vào:

Code:

var obj = {}; //new, empty object
obj['member_1'] = 'this is the member value';
obj['flag_2'] = false;
obj['some_function'] = function(){ /* do something */};


VD trên thực hiện công việc giống hệt với VD dưới đây:

Code:

var obj = {
member_1:'this is the member value',
flag_2: false,
some_function: function(){ /* do something */}
};


Như vậy, khái niệm đối tượng và mảng kết hợp (hash) trong JS là không phân biệt. 2 dòng dưới đây thực hiện cùng 1 công việc:

Code:

obj.some_function();
obj['some_function']();


4. Lớp

Sức mạnh to lớn của ngôn ngữ lập trình hướng đối tượng có được nhờ việc sử dụng lớp. Tôi không nghĩ rằng có thể dựa vào kinh nghiệm với các ngôn ngữ lập trình khác mà đoán ra được cách thức 1 lớp được định nghĩa trong JS (bởi nó... quá khác - ND):

Code:

//defining a new class called Pet
var Pet = function(petName, age){
this.name = petName;
this.age = age;
};

//let's create an object of the Pet class
var famousDog = new Pet('Santa\'s Little Helper', 15);
alert('This pet is called ' + famousDog.name);


Giờ hãy xem ta làm thế nào để thêm phương thức vào cho lớp Pet. Chúng ta sẽ sử dụng thuộc tính prototype mà mọi lớp trong JS đều có. Thuộc tính prototype là 1 đối tượng chứa tất cả các thành phần mà 1 đối tượng của lớp sẽ có. (Hay nôm na thuộc tính prototype chứa "nguyên mẫu" của 1 lớp, cho dễ hiểu.

- ND). Thậm chí các lớp mặc định của JS, như String, Number, Date,... đều có đối tượng prototype để ta có thể thêm vào đó các phương thức và thuộc tính giúp mọi đối tượng sinh ra từ lớp đó tự động có thêm các thành phần mới.
Code:

Pet.prototype.communicate = function(){
alert('I do not know what I should say, but my name is ' + this.name);
};


Đó là khi một thư viện như prototype.js tỏ ra tiện lợi. Nếu sử dụng prototype.js, ta có thể làm cho đoạn code sáng sủa hơn:

Code:

var Pet = Class.create();
Pet.prototype = {
//our 'constructor'
initialize: function(petName, age){
this.name = petName;
this.age = age;
},

communicate: function(){
alert('I do not know what I should say, but my name is ' + this.name);
}
};


5. Hàm đóng vai trò đối số

Code:

var myArray = ['first', 'second', 'third'];
myArray.each( function(item, index){
alert('The item in the position #' + index + ' is:' + item);
});


Trong VD trên, ta sử dụng thư viện prototype.js, nó sẽ thêm hàm each vào lớp Array (cụ thể thế nào tạm thời ta không cần quan tâm, khi nào nghiên cứu về prototype hãy hay - ND). Hàm each chấp nhận 1 đối số là 1 đối tượng hàm. Hàm này đến lượt nó sẽ được gọi một lần cho mỗi phần tử của mảng, với 2 đối số là phần tử hiện tại và chỉ số của nó. Ta có thể viết lại đoạn code trên như sau:

Code:

function myIterator(item, index){
alert('The item in the position #' + index + ' is:' + item);
}

var myArray = ['first', 'second', 'third'];
myArray.each( myIterator );



Trong TH này, ta không cần hàm iterator ở chỗ nào khác trong code, do đó nên viết theo cách đầu tiên với hàm ẩn danh.

6. This cũng có thể là that!

Một trong những vấn đề thường gặp nhất khi ta bắt đầu code JS là từ khóa this.

Như đã nói ở trên, 1 hàm trong JS cũng là 1 đối tượng, và đôi khi chúng ta không nhận thấy mình đang truyền 1 hàm đi vòng vòng. Lấy VD:

Code:

function buttonClicked(){
alert('button ' + this.id + ' was clicked');
}

var myButton = document.getElementById('someButtonID');
var myButton2 = document.getElementById('someOtherButtonID');
myButton.onclick = buttonClicked;
myButton2.onclick = buttonClicked;


Bởi vì hàm buttonClicked được định nghĩa bên ngoài mọi đối tượng, ta có thể sợ rằng từ khóa this sẽ chứa tham chiếu tới đối tượng window hoặc document.

Nhưng khi chạy đoạn code trên ta sẽ thấy nó làm việc đúng như mong đợi, và hiển thị lên id của button được click. Điều xảy ra ở đây là chúng ta đã khiến phương thức onclick của mỗi button chứa tham chiếu tới đối tượng buttonClicked. Và do đó mỗi khi một button được click, trình duyệt sẽ thực hiện công việc như dòng code sau:

Code:

myButton.onclick();


1 VD khác:

Code:

var myHelper = {

formFields: [ ],

emptyAllFields: function(){
for(i=0; i<this.formFields.length; i++){
var elementID = this.formFields[i];
var field = document.getElementById(elementID);
field.value = '';
}
}
};

//tell which form fields we want to work with
myHelper.formFields.push('txtName');
myHelper.formFields.push('txtEmail');
myHelper.formFields.push('txtAddress');

//clearing the text boxes:
myHelper.emptyAllFields();

var clearButton = document.getElementById('btnClear');
clearButton.onclick = myHelper.emptyAllFields;


Bây giờ bạn click button Clear và 3 textbox sẽ bị xóa. Sau đó bạn tiếp tục click nó, nhưng sẽ chỉ nhận được lỗi runtime. Lỗi này liên quan đến từ khóa this. Vấn đề ở đây là this.formFields chưa được định nghĩa, bởi vì this chứa tham chiếu tới đối tượng button (chứ không phải tham chiếu tới myHelper). Giải pháp nhanh gọn là viết lại dòng cuối cùng như sau:

Code:

clearButton.onclick = function(){ myHelper.emptyAllFields(); };

Bằng cách này ta đã tạo một hàm mới để gọi phương thức của helper trong ngữ cảnh của nó (this tham chiếu tới myHelper).

Đây là kiến thức cơ bản cần có trước khi chúng ta có thể dấn thân vào thế giới của các JS framework, hy vọng bài viết trên sẽ giúp các bạn tiêu hóa chúng dễ dàng hơn.


Report this post
Top
 Profile E-mail  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 


Who is online

Users browsing this forum: No registered users and 0 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron

Make Forum · php-BB© · Internationalization Project · Report abuse · Terms Of Use/Privacy Policy
© Forums-Free.com 2009