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);
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);
}
};
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
ManufacturerService
exports limited amount of methods, and totally open, but Car
instance is totally encapsulated and not even visible
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With