Monday, 11 March 2013

Public and Private Methods with Javascript

How to achieve public and private methods with Javascript

This is just a short post on how I construct my javascript objects to provide public and private method functionality (without using a framework). As much as I enjoy Javascript there are a million ways to do very similar things - hopefully this explains one good approach to do this.

What this approach provides you with:

  • Private methods
  • Public methods
  • Follows OOP practices

What this approach doesn't provide you with:

  • Inheritance :-(
  • If you want inheritance I highly recommend checking out the ExtJS framework. It's a very powerful framework that promotes good coding standards and architecture.

Why do I place high importance on using private methods/properties?

When I write any code I aim to hide as much of the complexity of the library from the outside world. The less functionality I have to expose to the outside world, the easier it is to refactor the code in the future, as you know exactly how your class can and can't be used.

So here is the example..

/**
 * A javascript object to manage data about a product (eg: book, computer, car or house etc..)
 */
var ProductInstance = function(id, name, price, discount){

    /**
     * ID of the product
     */
    var _id = id;

    /**
     * Name of the product
     */
    var _name = name;

    /**
     * Price of the product
     */
    var _price = price;

    /**
     * Discount of the product
     */
    var _discount = discount;

    /**
     * Private method to calculate discounted price
     */
    function _calculateDiscountedPrice() {
        var discountedPrice = _price;

        if( parseFloat(_discount) >  0 ) {
            discountedPrice = discountedPrice - _discount;
        }

        return discountedPrice;
    }

    /**
     * Private method to build up post data of an object
     */
    function _buildPostData() {
        var data = {}

        data.id = _id;
        data.name = _name;
        data.price = _price;
        data.discount = _discount;

        return data;
    }

    /**
     * Private method to save a product
     */
    function _save() {

        // You could save to local storage..

        // You could make an AJAX request to save to server..
        //$.ajax('/product/save/', _buildPostData());
    }

    /**
     * Public method to get Id
     */
    this.getId = function(){
        return _id;
    }

    /**
     * Public method to get Name
     */
    this.getName = function(){
        return _name;
    }

    /**
     * Public method to set name
     */
    this.setName = function(name){
        _name = name;
    }

    /**
     * Public method to get Price
     */
    this.getPrice = function(){
        return _price;
    }

    /**
     * Public method to set Price
     */
    this.setPrice = function(price){
        _price = price;
    }

    /**
     * Public method to get Discount
     */
    this.getDiscount = function(){
        return _discount;
    }

    /**
     * Public method to set Discount
     */
    this.setDiscount = function(discount){
        _discount = discount;
    }

    /**
     * Public method to set Discount
     */
    this.getDiscountedPrice = function(){
        return _calculateDiscountedPrice();
    }

    /**
     * Public method to save product
     */
    this.save = function(){
        return _save();
    }

    return this;
};

var productOne = new ProductInstance(1, 'Product One', 20, 5);
console.log(productOne.getId()); // equal "1"
console.log(productOne.getName()); // equal "Product One"
console.log(productOne.getPrice()); // equal "20"
console.log(productOne.getDiscount()); // equal "5"
console.log(productOne.getDiscountedPrice()); // equal "15"
//console.log(productOne._calculateDiscountedPrice()); // Method will not exist as method is private
//console.log(productOne._buildPostData()); // Method will not exist as method is private
//console.log(productOne._save()); // Method will not exist as method is private

var productTwo = new ProductInstance(2, 'Product Two', 50, 30);
console.log(productTwo.getId()); // equal "2"
console.log(productTwo.getName()); // equal "Product Two"
productTwo.setName("Product Two - Updated");
console.log(productTwo.getName()); // equal "Product Two - Updated"
console.log(productTwo.getPrice()); // equal "50"
console.log(productTwo.getDiscount()); // equal "30"
console.log(productTwo.getDiscountedPrice()); // equal "20"
//console.log(productTwo._calculateDiscountedPrice()); // Method will not exist as method is private
//console.log(productTwo._buildPostData()); // Method will not exist as method is private
//console.log(productTwo._save()); // Method will not exist as method is private

As you can see with the overly verbose example above, you can easily achieve public/private methods in Javascript. It's a very simple example, but in the real world your '_save' method could be quite complicated (even to the extend of using a different class to do the saving). Being able to hide all of that complexity from the outside world allows you to easily refactor it in the future. You can even unit test the above code quite easily as its not tightly coupled to any other components.



Dion Beetson
Founder of www.ackwired.com

1 comment:

  1. Great information with proper understanding.... Image mentioned is amazing and it signifies the article.
    mobile app development company | ipad app development company

    ReplyDelete