+2

Giới thiệu về lập trình hướng đối tượng trong Javascript

Với các dự án website thông thường, code javascript chiếm tỉ lệ khá nhỏ, chỉ khoảng 100-200 line of code. Có lẽ vì vậy mà code theo kiểu tự do khá phổ biến. Các bạn sẽ sử dụng trực tiếp các câu lệnh từ jQuery hoặc tổ chức function, bind sự kiện theo lập trình cấu trúc. Tuy nhiên cũng đừng quyên rằng javascript cũng có thể lập trình hướng đối tượng để phục vụ các ứng dụng đòi hỏi nhiều xử lý phía client, game chẳng hạn. Bài viết giới thiệu về lập trình hướng đối tượng trong javascript này sẽ dành cho những người đã biết về lập trình hướng đối tượng nhưng chưa áp dụng vào javascript.

1.Class

Đầu tiên, chúng ta sẽ định nghĩa một class

    var app = this.app || {};
    (function(scope){
        var Shape = function () {
            console.log(this);
        }
        scope.Shape = Shape;
    }(app));

Dòng thứ nhất khai báo namespace cho ứng dụng của bạn. Trong một ứng dụng các bạn có thể khai báo namespace theo chức năng hoặc nhóm chức năng. Tất nhiên, toàn bộ app của bạn chỉ có 1 namespace cũng không vấn đề gì. Sử dụng namespace để khởi tạo một instance của class Shape.

    var myShape = new app.Shape();

Bạn từng gặp cấu trúc này chưa ?

    (function(A){B}(C))

Cấu trúc này sẽ đóng gói định class Shape trong scope mà nó tạo ra. A là tham số truyền vào giống như trong định nghĩa function thông thường. C là biến mặc định của tham số A. Ở đây tôi đang áp dụng để truyền vào namespace. Với các ngôn ngữ khác nó sẽ giống như function(A = C){B}.

Dòng dưới đây định nghĩa object Shape

    var Shape = function () {};

Khi khởi tạo object với toán tử new. Browser sẽ thực thi các đoạn mã bên trong function. Trong ví dụ này là console.log(this); Và cuối cùng gán object mà chúng ta vừa định nghĩa vào namespace:

    scope.Shape = Shape;

Tiếp theo chúng ta sẽ thêm các thành phần khác để hoàn thiện class Shape

1.1. Thuộc tính

Chúng ta sẽ thêm các thuộc tính sau cho class Shape
static name
public height
public height
private color

    var app = this.app || {};
    (function(scope){
        var Shape = function () {
            console.log(this);
        }
        // static attribute
        Shape.name = 'shape';
        // public attribute
        Shape.prototype.height = 100;
        Shape.prototype.width = 100;
        // private attribute
        var color = 'red'
        scope.Shape = Shape;
    }(app));

1.2. Phương thức

Tương tự như vậy ta sẽ thêm phương thức vào class
static getName()
public perimeter()
private getColor()

    Shape.getName = function () {
        return Shape.name;
    }

    Shape.prototype.perimeter = function () {
        return 'perimeter';
    }

    var getColor = function () {
        return 'color';
    }

Cuối cùng là constructor

    var app = this.app || {};
    (function(scope){
        var Shape = function () {
            this.initialize()
        };

        Shape.prototype.initialize = function () {
            console.log('this is constructor');
        };

        scope.Shape = Shape;
    }(app));

Vậy là class Shape đã hoàn chỉnh. Cùng format cho đúng convention nào 😄

    var app = this.app || {};
    (function(scope){
        var Shape = function (width, height) {
            this.initialize(width, height);
        }

        var prototype = Shape.prototype;

        var color = 'color';
        Shape.name = 'shape';
        prototype.height = 100;
        prototype.width = 100;

        prototype.initialize = function (width, height) {
            this.width = width;
            this.height = height;
        };

        prototype.perimeter = function () {
            return 'perimeter';
        };

        Shape.getName = function () {
            return Shape.name;
        };

        var getColor = function () {
            return 'color';
        };

        scope.Shape = Shape;
    }(app));

2. Kế thừa

Bây giờ chúng ta sẽ định nghĩa lớp Rectangle kế thừa từ lớp Shape.

    var app = this.app || {};
    (function(scope){
        var Rectangle = function (width, height) {
            this.initialize(width, height);
        }

        var prototype = Rectangle.prototype = new scope.Shape();
        prototype.Shape_initialize = prototype.initialize;
        prototype.initialize = function (width, height) {
            this.Shape_initialize(width, height);
        };

        prototype.area = function () {
            return this.height * this.width;
        }

        scope.Rectangle = Rectangle;
    }(app));

Khá lằng nhằng đúng không 😄

    var prototype = Rectangle.prototype = new scope.Shape();
    prototype.Shape_initialize = prototype.initialize;

Đoạn này lưu tạm constructor của lớp cha

    prototype.initialize = function (width, height) {
            this.Shape_initialize(width, height);
    };

Còn đoạn này định nghĩa constructor của lớp con và gọi constructor của lớp cha. Như vậy là chúng ta đã tạo được 1 lớp cha và một lớp con. F12 và kiểm tra thành quả thôi.

    var shape = new app.Shape(10,10);
    var rec = new app.Rectangle(20,10);
    rec.area();
    rec.perimeter();

(Chúng ta sẽ phải chờ các trình duyệt nâng cấp javascript lên phiên bản ECMAScript 6 để có interface)
Cảm ơn các bạn đã theo dõi.

p/s: Bài viết dựa trên kinh nghiệm và kiến thức của bản thân người viết nên không tránh khỏi thiếu sót. Rất mong nhận được góp ý của quý vị.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.