Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three different ways of using javascript functions, but I don't know the pros and cons for it. Could someone explain the differences?

Tags:

javascript

I have three ways of making a function and returning it. (Maybe there is more?) but I don't know the differnce between them and when to use which. Could someone please explain.

var test1 = function() {
    var funk1 = function() {
        console.log(1);
    }
    var funk2 = function(msg) {
        console.log(msg);
    }
    return {
        funk1: funk1,
        funk2: funk2
    }
};

var test2 = function() {
    this.funk1 = function() {
        console.log(1);
    }
    this.funk2 = function(msg) {
        console.log(msg);
    }
};

var someThing = test1();
someThing.funk1();
someThing.funk2(2);

var someThing = new test1();
someThing.funk1();
someThing.funk2(2);

var thingElse = new test2();
thingElse.funk1();
thingElse.funk2(2);
like image 350
Rick Brunstedt Avatar asked Sep 25 '22 09:09

Rick Brunstedt


1 Answers

This is module/library/plugin pattern

var test1 = function() {
    var funk1 = function() {
        console.log(1);
    }
    return {
        funk1: funk1
    }
};

This is OOP(Object-Oriented-Programming) pattern

var test2 = function() {
    this.funk1 = function() {
        console.log(1);
    }
};

Difference

var t = test1() //function call, t is result of test1 function execution
var t = new test1() //instance initialization, t is instance of test1 class

Consider this simple model

We have a manufacturer that makes cars, manufacturer has some methods, and a car has it's own methods, we won't to tweak into manufacturer public properties, but still we cannot access the technology that manufacturer uses to create a car, so car is black box, that exposes some public props, and cannot be tweaked.

//service for creating/controlling manufactorer
var ManufacturerService = function(companyName) {
    var self = this;
    self.companyName = companyName;

    //encapsulation
    var Car = function(name, number){
        var createdAt = new Date();
        var engineStarts = 0;

        //instance property, doesn't have setter
        Object.defineProperty(this, 'info', {
            get: function(){
                return {
                    name: name,
                    createdAt: createdAt,
                    engineStarts: engineStarts
                }
            }
        });

        //instance method
        this.startEngine = function(){
            //private property, available only on instance, and cannot be extracted
            engineStarts++;

            //reference to ManufacturerService.companyName
            console.log(self.companyName + ' ' + name + ':' + number + ' engine Started');
        }
    }
    var createCar = function(name){
        //check cache/duplication/validation
        //or use custom behavior
        var carNumber = ManufacturerService.genShortUid();
        return new Car(name, carNumber);
    }
    var getName = function(){
        return self.companyName;
    }
    return {
        getName: getName,
        createCar: createCar
    }
};
//static method, this can be overriden by 3rdParty or user 
ManufacturerService.genShortUid = function genShortUid() {
    return ('0000' + (Math.random()*Math.pow(36,4) << 0).toString(36)).slice(-4);
}

Usage, the ManufacturerService is written as plugin/library, but notice that Car model is fully encapsulated, which means model is totally hidden from outside world

//create a service instance
var VolvoCompany = new ManufacturerService('Volvo');

//access encapsulated Car model by createCar method
//which is available only on instance of service
var Golf = VolvoCompany.createCar('Golf');

//instance method of car Model
Golf.startEngine(); //logs Volvo Golf:vnv6 engine Started

Golf.info
//returns 
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1}

//try to hack car instance
Golf.info.name = 'test';
Golf.name = 'test';

Golf.info
//returns same object, as Car model doesn't have exported setters
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1}    

//customize guid generator of ManufacturerService
ManufacturerService.genShortUid = function(){
    return '1111';
}

//reuse same service for another Car model
var Mazda = VolvoCompany.createCar('Mazda');

//instance method of car Model
Mazda.startEngine(); //logs Volvo Mazda:1111 engine Started

Summary

ManufacturerService exports limited amount of methods, and totally open, but Car instance is totally encapsulated and not even visible

edits/suggestions/comments are welcome

like image 98
Medet Tleukabiluly Avatar answered Oct 12 '22 12:10

Medet Tleukabiluly