Javascript: Private and Public properties and methods

Ở những bài viết trước, có lần chúng tôi đã nói về scope nhằm giúp các bạn mới bước vào Javascript có cái nhìn rõ ràng về scope thì bài viết này sẽ giúp các bạn hiểu hơn nữa về scope đó là Private và Public method và properties trong javascript. 

✔ Yêu cầu người đọc: 

1 - Hiểu về structure Javascript? 

2 - Scope trong javascript? 

3 - Đương nhiên chưa hiểu về Private và Public method và properties 

4 - Hiểu JavaScript Module Pattern. 

✔ Vì sao hiểu Private và Public method và properties 

Hẳn trong chúng ta rất nhiều các bạn đã viết cho mình nhiều modules trong qúa trình làm các dự án, nhưng tôi đoán rất ít bạn sử dụng private method trong dự án của mình. Đa số đều public method or properties của mình ra ngoài. Và kể từ đó bất kỳ ở đâu cũng truy cập được các method or properties của các bạn. Tất nhiên không có gì phải sợ mất mát hay rò rỉ data nếu bạn chưa có bất kỳ một dấu hiệu nào cho thấy bạn đang triển khai ứng dụng secure. Modules thông thường 

Chúng ta hãy cùng xem đoạn code sau, ví dụ được lấy từ bài viết của tác giả Kamran Ahmed

Ví dụ:

var FeedReader = {
 
    settings: {
        feedItemsCount: 10,
        url: 'http://someurl.com/news/feed/',
        feedListing: $('div#feedListing'),
        loadFeedButton: $('a.loadFeed')
    },
 
    init: function () {
        FeedReader.showErrorIfSourceDead();
        FeedReader.bindUI();
    },
 
    bindUI: function () {
        FeedReader.settings.loadFeedButton.on('click', function ( e ) {
            e.preventDefault();
            FeedReader.fetchFeed();
        });
    },
 
    showErrorIfSourceDead: function () {
        if ( FeedReader.isSourceAlive( FeedReader.settings.url ) === false ) {
            alert("The URL provided can't be used to fetch feed.");
        }
    },
 
    isSourceAlive: function () {
       // ...
    },
 
    fetchFeed: function () {
        // Fetch feed from the `FeedReader.settings.url`
        // Append the feed to the `FeedReader.settings.feedListing`
    }
};

Thoạt nhìn ta thấy code rất tốt, thông thoáng dễ hiểu và bảo trì trong tương lại. Nhưng hình như ở đâu đó chúng ta đang gặp một số vần đề ở đây. Sau một lúc chú ý thì chúng ta thấy đây là một module public. Vì tất cả các properties và method đều có thể truy cập ở bên ngoài hay bất cứ ở đâu?

hãy xem thử gọi:

console.log(FeedReader.settings.feedItemsCount)

Oh nó truy cập được. Hình như ở đây không có một private method hay properties nào hết. Tất cả là public. Nói cách khác, một số ngôn ngữ lập trình cho phép properties chỉ có thể truy cập được bởi đối tượng "sở hữu" nó. Để kỹ thuật hơn, một properties riêng chỉ hiển thị cho class hiện tại. Nó không thể truy cập trong phạm vi toàn cầu hoặc bất kỳ class con nào của nó. Vì vậy trong bài viết này chúng tôi sẽ giới thiệu cho các bạn cách tạo ra một module chứa Private and Public properties and methods. 

✔ Creating a Module

Đầu tiên, chúng ta đi từng bước một để giải thích một cách hay hơn về cách tạo private và public method. Để tạo một module thông thường ta làm như thế này:

// Person Module
var Person = function ( name ) {
    // Do some stuff here    
}

Và sử dụng thế này:

const _person = new Person('anonystick');

Chính xác và chúng ta xây dựng một private method và properties theo dạng này luôn. 

✔ Private Scope

Hầu hết trong khi triển khai một module, điều đầu tiên chúng ta luôn đặt vấn đề secure lên hàng đầu cho việc phát triển ứng dụng. Vì vậy các bạn nên tránh công khai một số dữ liệu nhảy cảm, tránh cho phép các đối tượng bên ngoài truy cập nhằm chuẩn bị cho một cuộc tấn công vào ứng dụng của chúng ta. 

Ví dụ:

 // Person Module
var Person = function ( name ) {
    
    // Private variables and functions that
    // ..cannot be accessed outside this Module
    var age     = 0,
        isAlive = true,
        name    = name || 'Un-named';
    
    var growOld = function () { 
        age++; 
    }

    var die = function () {
        isAlive = false;
    }
}

Bây giờ chúng ta thử gọi

// Create a person named Foo Bar
var FooBar = new Person('Foo Bar');

// TypeError: undefined is not a function
FooBar.growOld();
FooBar.die();

// undefined
console.log( FooBar.isAlive );

Vâng rất rõ ràng nếu call sẽ ra underfined. Và để tương tác với Person module chúng ta sẽ có những public method. 

✔ Public Scope 

Để viết Public properties và methods, tất cả những gì bạn phải làm là return về một object từ module, tức là module của bạn. Các properties và methods mà object này sở hữu sẽ được public và có thể truy cập được bên ngoài module Person.

// Person Module
var Person = function ( name ) {
    
    // Private variables and functions
    // ...
    

    // All the properties and methods contained by 
    // ..this object being returned will be public
    // ..and will be accessible in the global scope.
    return {
        passTime: function() {

        },

        speak : function () {

        }
    }
}

Code Full:

// Person Module
var Person = function ( name ) {
    
    // Private variables and functions that only
    // ..other private or public functions may access
    // ..and cannot be accessed outside this Module
    var age       = 0,
        maxAge    = 30,
        maxWeight = 80,
        isAlive   = true,
        weight    = 20,
        name      = name || 'Un-named';
    
    var growOld = function () { 
        if ( age++ >= maxAge ) {
            die();
        }
    }
    var gainWeight = function () { 
        weight++;
        if ( weight >= maxWeight ) {
            die();
        }
    }

    var loseWeight = function () { 
        weight--;
        if ( weight <= 0 ) {
            die();
        }
    } 

    var die = function () { isAlive = false; }
    

    // All the properties and methods contained by 
    // ..this object being returned will be public
    // ..and will be accessible in the global scope.
    return {
        speak : function () { 
            if ( !isAlive ) {
                alert('Dead man can\'t speak.');
                return;
            }

            alert('Speaking...');
            growOld(); 
        },

        walk : function () { 
            if( !isAlive ) {
                alert('Dead man can\'t walk');
                return;
            }

            alert('Walking'); 
            growOld(); 
            loseWeight(); 
        },

        eat : function () {
            if ( !isAlive ) {
                alert('Dead man can\'t eat');
            }
            gainWeight(); 
        }
    }
}

Bạn có thể check lại tại working demo of the module at jsfiddle.

Tôi hy vọng bạn đã có được sự hiểu biết tốt về cách đạt được Private and Public properties và methods trong Javascript sau khi đọc bài viết này. Ngoài ra, bạn nên biết rằng có nhiều cách khác để đạt được điều tương tự tuy nhiên cách được đề cập trong bài viết này có lẽ sẽ đủ. 

Nếu bài viết chưa giúp bạn hoặc có bất kỳ phản hồi nào thì chúng tôi mong các bạn để lại một bình luận giúp chúng tôi cải thiện. 

Thanks for Kamran Ahmed