Can someone explain this OOP javascript structure - javascript

Can someone explain this OOP javascript structure?
I realize it is how you create 'objects' in javascript, just need some explanation on the notation and what it means:
var vote = function(){
return {
P1: function() {
alert('P1');
},
P2: function() {
alert('P2');
}
};
}();
vote.P1();
vote.P2();
Why are the public methods in the return call? How is this possible? Separated by commas?
Why does the end of the 'object' have to be (); ?
Naming convention for internal methods and public methods?
Are public properties and methods the same structure? What is the difference?

var vote = function(){
var privateMember = 3; // lets define a private member, this will only be available inside the function scope, so we can't do "vote.privateMember" because we're not returning it below
// It's returning an object, {}
// these are considered public because they are returned by the function, making them available outside the function scope using the "dot" operator, "vote.P1()"
return {
// first value of the object is a function
// so we can call this like "vote.P1()"
// we're calling a privateMember in here
P1: function() {
alert('P1');
alert(privateMember);
},
// second value of the object is a function
// so we can call this like "vote.P2()"
P2: function() {
alert('P2');
}
};
}(); // () means it will execute the function, so "vote" will store the return value of this function, it's a shorthand for `var vote = function(){}; vote = vote();
Naming convention for private methods is usually to put an underscore before the method/property name _privateMethod: function(){}.

It's returning the object/hash. Notice that right after the return is a { which is the beginning of the object/hash.
to run the anonymous function that returns the object.
I don't know what you mean.
Yes they are the same. A property can be a function because javascript has first class functions.
This code is contrived so it's hard to say anything useful about it. I'm not sure what the authors intent was. It looks like he may have been aiming to create a class like thing, as opposed to the way javascript does prototype based OO. This code could have just as easily been written.
var vote = {
P1: function() {
alert('P1');
},
P2: function() {
alert('P2');
}
};

Three important concepts: anonymous functions, object literals, closure.
Anonymous Functions
You can declare and execute a function without assigning it to a variable. In you example, foo isn't a function, it's the result of calling:
var item = function(){ /*function code here*/ }**()**; <- Because the function is being executed, item is the object the function returned, not the function.
Object Literals
Say you did this: var a = new Object(); a.foo = 'bar';
Object literal notation would look like this: var a = {foo: 'bar'};
In you example, your anonymous function is returning a new object with two functions, P1 and P2. It's just a different notation for specifying objects.
Closure
When a function returns an object, that object retains access to the functions scope - this is called a closure. So, if you do this:
var a = function(){
var _pvt = 'foo';
return {
aFunc: function(){alert(_pvt);}
};
}();
a.aFunc();
_pvt's scope is the anonymous function. This function returns a new object with one method (aFunc). The anonymous function's scope is available to this object through closure, so when a.aFunc() is called, _pvt will be available.
Best place to learn about this is the Douglas Crockford videos on YUI Theater: http://video.yahoo.com/watch/111585/1027823

This is JSON (javascript object notations). It's similar to dictionary format in python.
Arrays can be defined inline using
[1,2,3,4,5]
and objects can be defined inline using
{ field1: value1, field2: value2, field3: value3 }
A function can be defined inline too,
var a = function() { .... } //a is a function
The () after the function is used to call the function immediately after its definition! Because the function is defined inline, it's like saying:
x = function() { ... }
y = x();
but condensed as:
y = function(){...} ();
As far as I know, there's no public or private, it's all public, and functions are no different from variables, it's just that their type is a function.

Related

How can I pass 'this' object to lower function in javascript? [duplicate]

In C++, the language I'm most comfortable with, usually one declares an object like this:
class foo
{
public:
int bar;
int getBar() { return bar; }
}
Calling getBar() works fine (ignoring the fact that bar might be uninitialized). The variable bar within getBar() is in the scope of class foo, so I don't need to say this->bar unless I really need to make it clear that I'm referring to the class' bar instead of, say, a parameter.
Now, I'm trying to get started with OOP in Javascript. So, I look up how to define classes and try the same sort of thing:
function foo()
{
this.bar = 0;
this.getBar = function() { return bar; }
}
And it gives me bar is undefined. Changing the bar to this.bar fixes the issue, but doing that for every variable clutters up my code quite a bit. Is this necessary for every variable? Since I can't find any questions relating to this, it makes me feel like I'm doing something fundamentally wrong.
EDIT: Right, so, from the comments what I'm getting is that this.bar, a property of an object, references something different than bar, a local variable. Can someone say why exactly this is, in terms of scoping and objects, and if there's another way to define an object where this isn't necessary?
JavaScript has no classes class-based object model. It uses the mightier prototypical inheritance, which can mimic classes, but is not suited well for it. Everything is an object, and objects [can] inherit from other objects.
A constructor is just a function that assigns properties to newly created objects. The object (created by a call with the new keyword) can be referenced trough the this keyword (which is local to the function).
A method also is just a function which is called on an object - again with this pointing to the object. At least when that function is invoked as a property of the object, using a member operator (dot, brackets). This causes lots of confusion to newbies, because if you pass around that function (e.g. to an event listener) it is "detached" from the object it was accessed on.
Now where is the inheritance? Instances of a "class" inherit from the same prototype object. Methods are defined as function properties on that object (instead of one function for each instance), the instance on which you call them just inherits that property.
Example:
function Foo() {
this.bar = "foo"; // creating a property on the instance
}
Foo.prototype.foo = 0; // of course you also can define other values to inherit
Foo.prototype.getBar = function() {
// quite useless
return this.bar;
}
var foo = new Foo; // creates an object which inherits from Foo.prototype,
// applies the Foo constructor on it and assigns it to the var
foo.getBar(); // "foo" - the inherited function is applied on the object and
// returns its "bar" property
foo.bar; // "foo" - we could have done this easier.
foo[foo.bar]; // 0 - access the "foo" property, which is inherited
foo.foo = 1; // and now overwrite it by creating an own property of foo
foo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that
(new Foo).foo; // is still 0
So, we did only use properties of that object and are happy with it. But all of them are "public", and can be overwritten/changed/deleted! If that doesn't matter you, you're lucky. You can indicate "privateness" of properties by prefixing their names with underscores, but that's only a hint to other developers and may not be obeyed (especially in error).
So, clever minds have found a solution that uses the constructor function as a closure, allowing the creating of private "attributes". Every execution of a javascript function creates a new variable environment for local variables, which may get garbage collected once the execution has finished. Every function that is declared inside that scope also has access to these variables, and as long as those functions could be called (e.g. by an event listener) the environment must persist. So, by exporting locally defined functions from your constructor you preserve that variable environment with local variables that can only be accessed by these functions.
Let's see it in action:
function Foo() {
var bar = "foo"; // a local variable
this.getBar = function getter() {
return bar; // accesses the local variable
}; // the assignment to a property makes it available to outside
}
var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototype
foo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor
This getter function, which is defined inside the constructor, is now called a "privileged method" as it has access to the "private" (local) "attributes" (variables). The value of bar will never change. You also could declare a setter function for it, of course, and with that you might add some validation etc.
Notice that the methods on the prototype object do not have access to the local variables of the constructor, yet they might use the privileged methods. Let's add one:
Foo.prototype.getFooBar = function() {
return this.getBar() + "bar"; // access the "getBar" function on "this" instance
}
// the inheritance is dynamic, so we can use it on our existing foo object
foo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix
So, you can combine both approaches. Notice that the privileged methods need more memory, as you create distinct function objects with different scope chains (yet the same code). If you are going to create incredibly huge amounts of instances, you should define methods only on the prototype.
It gets even a little more complicated when you are setting up inheritance from one "class" to another - basically you have to make the child prototype object inherit from the parent one, and apply the parent constructor on child instances to create the "private attributes". Have a look at Correct javascript inheritance, Private variables in inherited prototypes, Define Private field Members and Inheritance in JAVASCRIPT module pattern and How to implement inheritance in JS Revealing prototype pattern?
Explicitly saying this.foo means (as you've understood well) that you're interested about the property foo of the current object referenced by this. So if you use: this.foo = 'bar'; you're going to set the property foo of the current object referenced by this equals to bar.
The this keyword in JavaScript doesn't always mean the same thing like in C++. Here I can give you an example:
function Person(name) {
this.name = name;
console.log(this); //Developer {language: "js", name: "foo"} if called by Developer
}
function Developer(name, language) {
this.language = language;
Person.call(this, name);
}
var dev = new Developer('foo', 'js');
In the example above we're calling the function Person with the context of the function Developer so this is referencing to the object which will be created by Developer. As you might see from the console.log result this is comes from Developer. With the first argument of the method call we specify the context with which the function will be called.
If you don't use this simply the property you've created will be a local variable. As you might know JavaScript have functional scope so that's why the variable will be local, visible only for the function where it's declared (and of course all it's child functions which are declared inside the parent). Here is an example:
function foo() {
var bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(f.getBar()); //'foobar'
This is true when you use the var keyword. This means that you're defining bar as local variable if you forget var unfortunately bar will became global.
function foo() {
bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(window.bar); //'foobar'
Exactly the local scope can help you to achieve privacy and encapsulation which are one of the greatest benefits of OOP.
Real world example:
function ShoppingCart() {
var items = [];
this.getPrice = function () {
var total = 0;
for (var i = 0; i < items.length; i += 1) {
total += items[i].price;
}
return total;
}
this.addItem = function (item) {
items.push(item);
}
this.checkOut = function () {
var serializedItems = JSON.strigify(items);
//send request to the server...
}
}
var cart = new ShoppingCart();
cart.addItem({ price: 10, type: 'T-shirt' });
cart.addItem({ price: 20, type: 'Pants' });
console.log(cart.getPrice()); //30
One more example of the benefits of the JavaScript scope is the Module Pattern.
In Module Pattern you can simulate privacy using the local functional scope of JavaScript. With this approach you can have both private properties and methods. Here is an example:
var module = (function {
var privateProperty = 42;
function privateMethod() {
console.log('I\'m private');
}
return {
publicMethod: function () {
console.log('I\'m public!');
console.log('I\'ll call a private method!');
privateMethod();
},
publicProperty: 1.68,
getPrivateProperty: function () {
return privateProperty;
},
usePublicProperty: function () {
console.log('I\'ll get a public property...' + this.publicProperty);
}
}
}());
module.privateMethod(); //TypeError
module.publicProperty(); //1.68
module.usePublicProperty(); //I'll get a public property...1.68
module.getPrivateProperty(); //42
module.publicMethod();
/*
* I'm public!
* I'll call a private method!
* I'm private
*/
There's a little strange syntax with the parentless wrapping the anonymous functions but forget it for the moment (it's just executing the function after it's being initialized). The functionality can be saw from the example of usage but the benefits are connected mainly of providing a simple public interface which does not engages you with all implementation details. For more detailed explanation of the pattern you can see the link I've put above.
I hope that with this :-) information I helped you to understand few basic topics of JavaScript.
function Foo() {
this.bar = 0;
this.getBar = function () { return this.bar };
}
When you call the function above with the new keyword - like this...
var foo = new Foo();
... - a few things happen:
1) an object is created
2) the function is executed with the this keyword referencing that object.
3) that object is returned.
foo, then, becomes this object:
{
bar: 0,
getBar: function () { return this.bar; }
};
Why not, then, just do this:
var foo = {
bar: 0,
getBar: function () { return this.bar; }
};
You would, if it's just that one simple object.
But creating an object with a constructor (that's how it's called) gives us a big advantage in creating multiple of the "same" objects.
See, in javascript, all functions are created with a prototype property [an object], and all objects created with that function (by calling it with the new keyword) are linked to that prototype object. This is why it's so cool - you can store all common methods (and properties, if you wanted to) in the prototype object, and save a lot of memory. This is how it works:
function Foo( bar, bob ) {
this.bar = bar;
this.bob = bob;
}
Foo.prototype.calculate = function () {
// 'this' points not to the 'prototype' object
// as you could've expect, but to the objects
// created by calling Foo with the new keyword.
// This is what makes it work.
return this.bar - this.bob;
};
var foo1 = new Foo(9, 5);
var foo2 = new Foo(13, 3);
var result1 = foo1.calculate();
var result2 = foo2.calculate();
console.log(result1); //logs 4
console.log(result2); //logs 10
That's it!
To get closer to OOP in JavaScript, you might want to take a look into a Module design pattern (for instance, described here).
Based on the closure effect, this pattern allows emulating private properties in your objects.
With 'private' properties you can reference them directly by its identifier (i.e., no this keyword as in constructors).
But anyway, closures and design patterns in JS - an advanced topic. So, get familiar with basics (also explained in the book mentioned before).
In javascript this always refers to the owner object of the function. For example, if you define your function foo() in a page, then owner is the javascript object windows; or if you define the foo() on html element <body>, then the owner is the html element body; and likewise if you define the function onclick of element <a>, then the owner is the anchor.
In your case, you are assigning a property bar to the 'owner' object at the begining and trying to return the local variable bar.
Since you never defined any local varialbe bar, it is giving you as bar is undefined.
Ideally your code should have defined the variable as var bar; if you want to return the value zero.
this is like a public access modifier of objects(variables or functions), while var is the private access modifier
Example
var x = {};
x.hello = function(){
var k = 'Hello World';
this.m = 'Hello JavaScript';
}
var t = new x.hello();
console.log(t.k); //undefined
console.log(t.m); //Hello JavaScript

What is it called when a function behaves like a class but doesn't use the class keyword, nor "new" keyword (in Javascript)?

I looked through the suggested links but can't seem to find the term for a function that acts like a class (is it a constructor function? doesn't have that keyword either!) but doesn't use the new keyword, nor class.
I've used both this example's pattern and the class pattern in my code but realized I don't know how to describe the former.
I think this is in part because I learned JS recently, have seen class thrown around a lot, yet looking through my notes of not-ES5,6,7,2018,2020 etc. can't seem to find what var aCounter = counterFunction() is called for the life of me.
I know what the result of what i'm doing is, how to work it, etc. but why no constructor(), no new, no class, no etc.prototype.etc pattern? I know i'm creating an object, calling a method existing Within the object, etc. I believe i'm beginning to ramble.
Lo, an example
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
which is || can be instantiated (?) like so:
let aCounter = counterFunction() // where i'm getting tripped up
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
I know this is rambling, but help! I think it will make things click more inside once this lexical puzzle piece is put into position!
That is just a function that returns an object literal, which does not act like a class (doesn't have a prototype, and as you pointed out, does not use new, etc).
The functions that are set as the properties of this object (which you store in aCounter) seem to act like class methods because they keep the reference to the variable val alive, but this is not because val is in any way associated with the actual object.
Instead, those functions are closures that keep the reference to the variable alive for as long as the functions themselves are alive.
So to answer your question, what you have described doesn't have any name in particular. It's just a function that returns an object.
Edit:
You asked why there is no constructor() or related syntax in this pattern. Object literals in JavaScript are just mappings of names and values:
const x = { a: 3, b: "hello" };
You do not need a constructor for this, and there is no prototype because it was not instantiated using a constructor. On the other hand, classes and constructor functions are templates for objects that will be created later, and those objects do have a prototype and a constructor because the template contains logic that initializes the object.
class A
{
constructor()
{
this.a = new Date();
this.b = this.a.toString(); // you cannot do this in an object literal
}
}
const x = new A();
Question:
What is it called when a function behaves like a class but doesn't use the class keyword, nor “new” keyword (in Javascript)?
Answer:
It's called a "factory function".
Factory functions usually return a object of a consistent type but are not instances of the factory function itself. Returned objects would rarely inherit from the factory function's prototype property, and calling the factory function does not require new before the function being called.
What you showed there is nothing special. It is just a normal function that has a closure.
Though, you can call it as a type of design pattern.
It looks similar to Revealing Module Pattern where you can separate public property and private property.
Below is an example (not a good one tho):
var counter = function(){
var privateCount = 0;
var privateHistory = [];
return {
getVal: function(){
return privateCount;
},
increment: function(){
privateCount++;
privateHistory.push('+');
return this.getVal();
},
decrement: function(){
privateCount--;
privateHistory.push('-');
return this.getVal();
},
publicHistory: function(){
return privateHistory;
}
}
}
var aCounter = counter();
console.log(aCounter.increment());
console.log(aCounter.decrement());
console.log(aCounter.publicHistory());
Here, you can't directly manipulate the private variables that I don't expose to you.
You can only manipulate those private variables only if I expose the function to you. In this case, the .increment() and .decrement() function.
As you can see, there is no class, no prototype, no constructor.
I can see how you may get tripped up, let's go through your code and explore what's going on:
const counterFunction = () => {
let val = 0
return {
increment() { val++ },
getVal() { return val }
}
}
At this point counterFunction is a variable that points to a function, it's essentially a function name. The ()=>{...} is the function body or function definition and within it the return statement shows that it returns an unnamed object with two property methods.
let aCounter = counterFunction() // where i'm getting tripped up
This is calling your previously defined function, which again returns the object with two methods and assigns it to the variable aCounter. If you did the same thing again for a variable called bCounter they would hold two independent objects.
and works like
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2
Because the method inside the object refers to a variable outside the scope of the object, but within the function body, a closure is created so that the state of val may be retained. Because the variable is in use, the browser's cleanup process skips over it, so the function is still kept in memory, I believe until the object is destroyed and the function's variable is no longer used.

What does "Object.call" mean?

function bb_graphics_GraphicsContext(){
Object.call(this);
this.bbdevice=null;
this.bbmatrixSp=0;
this.bbix=1.000000;
this.bbiy=0;
this.bbjx=0;
this.bbjy=1.000000;
this.bbtx=0;
this.bbty=0;
this.bbtformed=0;
this.bbmatDirty=0;
this.bbcolor_r=0;
this.bbcolor_g=0;
this.bbcolor_b=0;
this.bbalpha=0;
this.bbblend=0;
this.bbscissor_x=0;
this.bbscissor_y=0;
this.bbscissor_width=0;
this.bbscissor_height=0;
this.bbmatrixStack=new_number_array(192);
}
What does Object.call(this) mean?
Functions in JavaScript are full-fledged objects. They also, when passed as an argument to another function, don't retain their scope. So, in the following code...
var obj1 = {
property1: "blah",
method1: function () {
alert(this.property1);
// do stuff
}
};
function func1 (passedFunction) {
passedFunction();
// do other stuff
}
func1(obj1.method1);
... func1 will call obj1.method1, but it won't alert the value of obj1's property1, because all we've done is pass the function object, not its this context. That's where call and apply come in. They allow you to inject scope, tell the function what the meaning of this will be. The following example works:
var obj1 = {
property1: "blah",
method1: function () {
alert(this.property1);
// do stuff
}
};
function func1 (passedObject, passedFunction) {
passedFunction.call(passedObject);
// do other stuff
}
func1(ob1, obj1.method1);
Now, we've forced or explicitly told obj1.method1 what its context will by invoking call, and passing it the object it's to use as this.
call and apply are almost identical, except for how they handle additional arguments to the function being invoked. See these articles on MDN for more information: call, apply and Function.
All of this having been said, bb_graphics_GraphicsContext is a constructor. (Which you've probably guessed.) You invoke it by using the new keyword, var obj1 = new bb_graphics_GraphicsContext();. When it reaches line 1 of the function, it takes the this object, and calls the generic Object constructor, explicitly injecting the new object this (in the bb_graphics_GraphicsContext constructor) as the this of the Object constructor. I'd assume the writer of this function/constructor was doing this to make sure that the newly created object in bb_graphics_GraphicsContext was getting all the base methods of the base Object. But I don't know why this would be necessary, as if you call bb_graphics_GraphicsContext with the new keyword it will grab all these properties naturally.
Object.call will execute a certain function under the provided context, it can be used to call functions from one object on an other.
The mozilla dev network provides a very good explanation
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call
This will do absolutely nothing except wasting resource and memory allocation.
If the Object.call(this) will have been assigned to a variable or property of the function constructor bb_graphics_GraphicsContext
this.myObject = Object.call(this)
The only thing that you get in that instance is an empty object "THAT DO NO HOLD THE PROVIDED CONTEXT"
function MyConstructor(){
this.test01 = 0;
var b = Object.call(this); // similar to b = {}; or b = new Object()
console.log(b); // log object
console.log(b.test); // log undefined
this.test = 1;
}
var myObject = new MyConstructor();
console.log(myObject, window.test01)
Although Object.call will probably do nothing as expressed here, the concept might be important. Basically, the example you will see on inheritance in the Node.js documentation is:
const util = require('util');
const EventEmitter = require('events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
The util.inherits will make a new MyStream inherit (have the same prototype as) EventEmmiter. This could be enough if we are interested in MyStream having access to the functions inherited through the EventEmmiter prototype. But what if there are variables passed on construction? What if we have:
function MyObject() {
this.code = "2nV_ahR";
}
In this case, the code variable is passed on runtime when MyObject gets instantiated. Therefore, a subclass needs to pass:
function MySubObject() {
MyObject.call(this);
}
In order to inherit the code variable. What call does accept a parameter that sets the this variable. So... when I do var o = new MySubObject(), the this inside of MySubObject refers to o, which is then passed to the call method, so that when MyObject does this.code = ... it is actually passing the code to o!
Every JavaScript function has a toString(), call() and apply().
Read more about them on this odetocode.com article

Namespaces in JavaScript: do I need to rewrite all my variable and function references?

I am namespacing some JavaScript code, and I want to know if I have rewritten all my function calls and references to global variables correctly. The current code is this:
var x = 10;
function foo() {
console.log('foo');
bar();
},
function bar() {
console.log('bar', x);
}
foo();
I have rewritten it as follows:
var namespace = {
x : 10,
foo: function() {
console.log('foo');
// Is this the correct way to call bar?
this.bar();
},
bar: function() {
// Is this the correct way to refer to x?
console.log('bar', this.x);
}
};
namespace.foo();
Is this correct, i.e. do I need to rewrite all function calls (EDIT: by which I mean all inside the namespace variable) to this.functionname() and all global variables to this.variablename?
If you like, you can make yourself some "real" private variables and methods by incorporating a closure. I favour the module pattern.
var ns = (function () {
var x = 10;
return {
foo: function () {
console.log('foo');
this.bar();
},
bar: function () {
console.log('bar', x);
},
increment: function () {
x++;
}
}
}());
ns.foo();
ns.increment();
ns.foo();
http://jsfiddle.net/DjYue/
No, in some places (code that calls those functions from outside of your namespace object) you would have to call namespace.foo(), namespace.bar(), namespace.varName
Actually, if you use namespace.bar() from the function in the object itself, you get the added benefit that your functions don't depend on context. That is, the following code doesn't work with what you have
var fun = namespace.foo;
fun(); // This would break, since the this value is going to be the global object
I usually don't like to use this from literal objects because of the problem mentioned above. It's definitely a preference, I just prefer to avoid problems with this
No, you shouldn't rewrite to this.funcname() but rather namespace.funcname(). The this keyword is reserved to refer to the current context object (or whatever it's called), meaning that you'd use it within your "namespaced" code to refer to the namespace object.
And generally, it's good to know that you aren't actually working with namespaces as you'd know it from more classical OOP. JavaScript is a prototype-based language, which means that you don't have namespaces - rather, what you're creating is an object containing several properties and methods. As previously mentioned, when you're working with methods of the object, the this keyword refers to the object itself. You'd need a reference to the object when outside of it's context.
Currently, the approach of using objects to contain all of your code as a sort of namespaces and classes in disguise is diminishing in favor of closures which attaches the methods and properties that should be publicly available to a function (which, in JavaScript, is a first class object), and either returns that function or attaches it to the global object. You may also, alternatively, use a function to contain the properties and methods instead of an object.
I disagree with the people who say No to your question. It really depends on what you want to accomplish here. Based the rewritten code, I don't see anything wrong with it. As long as you call namespace.foo(), the execution context of each function should be namespace. Thus, it is not wrong to use this.
There is a situation that invoking the function foo() will not work:
var foo1 = namespace.foo;
foo1();
Although foo1 is same as the function namespace.foo, foo1's execution context has changed. this will refer to window, not namespace.
Their is no need to rewrite that much because you can have more than one reference to a function - a private and a public one.
var namespace = (function() {
var ns = {}; // the 'namespace'
var x = 10;
var foo = // 'private' reference: bar();
ns.foo = // 'public' reference: ns.bar() -> namespace.bar();
function foo() { // the name is optional because it's a function expression
console.log('foo');
bar();
}; // don't forget the semicolon
var bar =
ns.bar =
function() {
console.log('bar', x);
};
return ns; // return the 'namespace'
})();
namespace.foo();
var foo = namespace.foo;
foo();
delete namespace.bar;
// namespace.bar(); // Error
foo(); // bar is called

Difference between a constructor and an Object

I definitely need some light on this.
What's the diference between:
var MY_APP = function(){
this.firstMethod = function(){
//something
};
this.secondMethod = function(){
//something
};
};
and
var MY_APP = {
firstKey: function(){
//something
},
secondKey: function(){
//something
}
};
besides the obvious fact that one is a Function and the other an Object, what are the differences in code flow, prototypes, patterns... whatever, and when should we use the first or the second?
I'm so spaced out in this area that i'm not sure if i'm correctly explaining the doubt, but further info can be given if you ask.
The key difference between the two is in how they are intended to be used. A constructor, as its name suggests, is designed to create and set up multiple instances of an object. An object literal on the other hand is one-off, like string and number literals, and used more often as configuration objects or global singletons (e.g. for namespacing).
There are a few subtleties about the first example to note:
When the code is executed, an anonymous function is created and assigned to MY_APP, but nothing else happens. firstMethod and secondMethod don't exist until MY_APP is explicitly called.
Depending on how MY_APP is called, the methods firstMethod and secondMethod will end up in different places:
MY_APP(): Since no context is supplied, the this defaults to window and the methods will become global.
var app1 = new MY_APP(): Due to the new keyword, a new object is created and becomes the default context. this refers to the new object, and the methods will get assigned to the new object, which subsequently gets assigned to app1. However, MY_APP.firstMethod remains undefined.
MY_APP.call(YOUR_APP): This calls my MY_APP but sets the context to be another object, YOUR_APP. The methods will get assigned to YOUR_APP, overriding any properties of YOUR_APP with the same names. This is a really flexible method that allows multiple inheritance or mixins in Javascript.
Constructors also allow another level of flexibility since functions provide closures, while object literals do not. If for example firstMethod and secondMethod rely on a common variable password that is private to the object (cannot be accessed outside the constructor), this can be achieved very simply by doing:
var MY_APP = function(){
var password = "GFHSFG";
this.firstMethod = function(){
// Do something with password
alert(password); // Woops!
};
this.secondMethod = function(){
// Do something else with password
};
};
MY_APP();
alert(password); // undefined
alert(MY_APP.password); // undefined
The first is a function, the second is an object literal. Since Functions in JS are first class objects, a function can have properties on it, just like any other object can.
Typically, if you want to create a "class" that you might be familiar with from classical inheritance languages, you would do something like
function MyClass() {...}
as is documented here http://www.crockford.com/javascript/inheritance.html
To answer the question posed in your edits, you would use them both in different situations. Object literals are used to pass configurations around. A typical usage pattern would be a method that accepts an object literal like so
something.init({
length: 10,
height: 10,
text: 'some text'
});
and so on.
You could use something similar to your first example when creating a namespace. Javascript has some interesting language features in that you can have so-called "self-invoking functions" that are of the form:
var myApp = (function(){
var firstMethod = function() {...}
...
})();
the motivations behind doing something like this are detailed here
http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/
You can also investigate the differences via your favorite javascript debugging console. In firebug and chrome, I did the following:
var ol = {}; ol.prototype;
var fn = function(){}; fn.prototype;
the first line prints undefined, the second returns a prototype with a constructor of 'function'
The constructor can be reused as is, the object literal would need to be repeated or wrapped in a function to be reused.
Example of wrapping the object literal in a function:
function MY_APP() {
return {
firstKey: function(){
//something
},
secondKey: function(){
//something
}
};
}
The object created using the constructor will have it's constructor property set to the constructor function. However, as you used an anonymous function assigned to a variable instead of a named function, the constructor will still be nameless.
Other than that, there isn't really any differences. Both create anonymous functions that are assigned to the properties of the object, so the resulting objects are the same. You can compare this to assigning named functions to the properties, or using prototype functions, both having the difference that each function only exists once instead of being created over and over for each object.
There is some confusion in JavaScript regarding the difference between a function and an object.
In the first case,
var MY_APP = function() { this.v = 7; ... }
or
function MY_APP(x) { this.v = x; ... }
a function is declared, not an object. In MY_APP, this refers to the global object.
Meaning that calling the function MY_APP(7) will assign v globally to the value of 7. (and in your case the function firstMethod would be declared globally).
MY_APP(3); // The global variable v is set to 3
MY_APP(4); // The global variable v is overwritten and set to 4
To use MY_APP as an object, it needs to be instantiated, for instance
var obj1 = new MY_APP(3);
var obj2 = new MY_APP(4);
will have obj1.v to be 3, and obj2.v to be 4.
Note you can also add methods using the prototype keyword (instead of this.firstMethod...)
MY_APP.prototype.firstMethod = function () { ... }
In the second case
var MY_APP = { ... };
an object, one object, is created and its name is MY_APP. The this keywords refers to that object, MY_APP.

Categories

Resources