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

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

Related

Differences between "this" in JavaScript and ActionScript

My background is heavy in JavaScript. I have a very advanced understanding of both ES5 and ES6. At work I was recently assigned a project involving an older flash application, which uses AS2. It is my understanding that ActionScript is very similar to ES5, but with classes and optional strict typing (akin to TypeScript and Flow), as well as a few other classic OO features. It is fairly straightforward so far, but I'm having trouble understanding how this and references work in ActionScript.
This is my understanding for JavaScript. this in a function can reference:
A bound variable, if using Function.bind() (as well as Function.call() and Function.apply()), which cannot be changed in the bound function, for example:
function func() {
return this.number;
}
var bound = func.bind({ number: 2 });
console.log(bound()); // 2
An object, if the function is called as a method on that object, for example:
function func() {
return this.number;
}
var obj = { number: 2, func: func };
console.log(obj.func()); // 2
An instance of a class, if that function is defined on the prototype of that class, for example:
function Class() {
this.number = 2;
}
Class.prototype.func = function func() {
return this.number;
}
console.log(new Class().func()); // 2
The global object, if the function is called without any kind of binding or object or instance attached to it, for example:
var number = 2;
function func() {
return this.number;
}
console.log(func()); // 2
In ActionScript things seem to be a bit different. For one thing, you can access class members without this if you are doing it within a method of that class, similar to languages like C# and Java:
class MyClass {
private var number:Number = 2;
public function func():Number {
return number;
}
}
trace(new MyClass().func()); // 2
Also, the ActionScript standard library doesn't seem to have a Function.bind() method, though it does have Function.apply() and Function.call() which seem to work just like the JavaScript variations: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/help.html?content=00001072.html#265677. There also don't seem to be prototypes, which makes sense because classes are more abstract syntactic structures rather than functions (just like C#/Java) based on my understanding.
So my question is, excluding the lack of Function.bind() and Function.prototype, are the rules the same between ActionScript and JavaScript?
In addition, what happens if I do this:
class SomeClip extends MovieClip {
private var childClip:MovieClip;
private var number:Number = 2;
public function SomeClip() {
this.onLoad = function() {
// SomeClip onLoad hander, `this` will be the SomeClip instance
childClip._visible = true; // How is childClip resolved here?
childClip.onRelease = function() {
// childClip onRelease handler, `this` will be childClip
trace(number); // How is number resolved here?
};
};
}
}
Basically, if you access a member without this in an event handler, or some other loose function that is not a method of the class, what happens? I would guess that in the first case, it would resolve to this.childClip and work as one would expect, but in the second case, the resolution would fail because the onRelease handler's closure won't contain a reference to the SomeClip instance.
I see the comments that have been written so far are more focused on JS, so I'll try my best to answer from an ActionScript perspective.
In the world of AS2/AS3, functions that are defined as methods on a class have their this value bound to the class. This is typical of many higher-level languages with modern classes, such as Java, Haxe, etc. As such, in ActionScript you'll rarely find the need to use the this keyword other than cases where a variable name might be shadowed by a function argument:
public function Point(x:Number = 0, y:Number = 0)
{
// A rare but necessary use-case of "this" in AS2/AS3
this.x = x;
this.y = y;
}
On the other hand, if the function you provide is anonymous as in the example you wrote, the behavior depends on whether or not you prepend this:
childClip.onRelease = function() {
trace(number);
};
In this case ActionScript is able to determine number is a member of the class, and will print 2 like you expected since. This is because the interpreter looks for the next closest thing in the stack. In other words, you were ambiguous by excluding this so it knows it needs to perform a lookup.
However if you were to trace(this.number) instead, you would find that you get an undefined (and possibly even an error). This is because this is not a member variable on the class, and now points to a "global object" similar to JS. To avoid dancing with the global object, it's common practice for ActionScript developers to define all of their listeners as class instance methods:
class MyClass extends EventDispatcher
{
private function MyClass()
{
addEventListener(Event.CHANGE, onChangeEvent);
}
private function onChangeEvent(e:Event) {
trace(this); // refers to this class, and no need for bind() like JS
}
}
Well organized AS3 code will almost never contain inline anonymous functions, since it's much easier to handle garbage collection by using explicit function references.
One last thing to note - you can expect functions that are methods of regular Objects in ActionScript to behave like JavaScript where passing them around via event listeners will result in the context of this being lost, and Flash will not do the magic lookup to locate the variable you referenced:
var obj = {
func: function () {
trace(this); // weird global object
}
};
addEventListener(Event.CHANGE, obj.func);
Hope that helps!
In AS2 functions are not bound and get "this" reference passed (evidently via Function.apply or by the object reference) in the moment of call:
function getIndex()
{
trace(this.index);
}
var A = {index:1, getIndex:getIndex};
var B = {index:2, getIndex:getIndex};
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 1
Binding methods to certain objects was called "delegating": http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001842.html#1001423 In a nutshell, functions are objects too and you can create special function object that has references to both method to call and "this" object to pass:
function getIndex()
{
trace(this.index);
}
function bind(method, target):Function
{
var result:Function = function()
{
// arguments.callee is always a reference
// to the current function object
arguments.callee.method.apply(arguments.callee.target);
}
result.method = method;
result.target = target;
return result;
}
var A = {index:1};
var B = {index:2};
A.getIndex = bind(getIndex, A);
B.getIndex = bind(getIndex, B);
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 2
Then, if you don't use "this" reference, once you address some variable by its name there are several contexts that are searched for such a variable in order:
local function variables
local wrapper function variables (this one is truly horrible for no one really knows where these variables exist and it is a potent memory leak)
MovieClip, that holds the function code, local variables
global variables
Play with the following code, comment some "index" variables and you'll see it:
// Global variable.
_global.index = 6;
// MovieClip local variable.
var index = 5;
function wrap():Function
{
// Wrapper function local variable.
var index = 4;
return function()
{
// Function local variable.
var index = 3;
trace(index);
}
}
wrap()();

Javascript: Generating a self executing class that is callable and extendable in window context

some beginner question here but i can't seem to find a working answer for my problem. I want to write a self executing, global javascript class 'foo' whose methods can be called from window context (like window.foo.bar() or just foo.bar() in javascript console), without having to instantiate the class.
At the same time, i want to be able to extend said class with custom functions, e.g.
foo.fn.baz = function() {}
This is how far i have gotten this far:
(function (window) {
var foo = function() {
return this;
};
foo.fn = foo.prototype = {
bar: function (string) {
console.log(string);
}
};
window.foo = foo;
})(window);
When i execute this javascript, the js console now knows the class foo, and i can extend its functions via foo.fn.baz = function(){} but i can't call those functions: foo.bar is undefined.
If i change the code from window.foo = foo; to window.foo = new foo();, then i can call the functions, but i can't extend the class anymore.
How do i do this rigt? Is my code anywhere near the right way to do such a thing? Is it even possible to get both things at the same time?
Anyone with an idea or a hint? Anything would be great.
thanks
foo.bar is undefined
Right. You've put the methods on the prototype property of the function. The object that foo.prototype refers to will get assigned to instances you create via the new operator, as their underlying prototype. So:
var f = new foo();
f.bar();
If you want a singleton (foo is, itself, the one object and you can call foo.bar()), you don't need prototypes at all:
window.foo = {
bar: function(string) {
console.log(string);
}
};
...but as you used the word "class," my guess is that you really do want to create multiple instances using foo, rather than using foo directly, so new foo() would be what you want.
Side note: The overwhelming convention in JavaScript is that if a function is expected to be called via new, it starts with an upper-case letter. So Foo rather than foo.

Creating functions for an object in javascript

As far as I can tell, there are two main ways of creating functions for an object in javascript. They are:
Method A, make it in the constructor:
function MyObject() {
this.myFunc1 = function() {
...
}
this.myFunc2 = function() {
...
}
...
}
Method B, add it to the prototype:
function MyObject() {
...
}
MyObject.prototype.myFunc1 = function() {
...
}
MyObject.prototype.myFunc2 = function() {
....
}
Obviously if you did:
MyObject.myFunc3 = function() {
....
}
then myFunc3 would become associated with MyObject itself, and not any new objects created with the new keyword. For clarity, we'll call it method C, even though it doesn't work for creating new objects with the new keyword.
So, I would like to know what the differences between the two are. As far as I can tell they have the same effect logically, even if what's happening on the machine is different.
If I were to guess I would say that the only real difference is when you're defining them in the constructor like in method A, it creates a whole new function object for each object that's created, and Method B only keeps one copy of it (in MyObject), that it refers to any time it's called. if this is the case, why would you do it one way over the other. Otherwise, what is the difference between method A and method B.
The advantage of giving a separate function to each object is that you can close over variables in the constructor, essentially allowing for "private data".
function MyObject(a,b) {
var n = a + b; //private variable
this.myFunc1 = function() {
console.log(n);
}
};
vs
function MyObject(a,b) {
this.n = a + b; //public variable
}
MyObject.prototype.myFunc1 = function() {
console.log(this.n);
}
Whether this is a good idea or not depends on who you ask. My personal stance is reserving constructor functions for when I actually use the prototype, as in option #2 and using plain functions (say, make_my_object(a,b)) when using closures, as in option #1.
The idea is that you can modify the prototype at any time and all objects of the type (even those created before the modification) will inherit the changes. This is because, as you mentioned, the prototype is not copied with every new instance.
The MyObject in method A is an instance for inner functions.
You cannot call its functions explicitly outside of it unless object (you can call it a class) was instantiated.
Assume this:
MyObject.MyFunc1(); // will not work
var obj = new MyObject();
obj.MyFunc1(); // will work
so this is the same as any class in other languages. Describing usefulness of classes and their usages goes beyond that question though.
Also to notice:
function MyObject() {
var privateVar = "foo";
this.publicProperty = "bar";
// public function
this.publicFunc = function() {
...
}
// private function
function privateFunc () {
...
}
}
For method B it's same as with method A, the only difference is prototyping is a style of creating object. Some use prototypes for readability or out of preference.
The main advantage in prototypes is that you can extend existing object without touching the original source. You need to be careful with that though.
(as example Prototype framework)
For method C you can call them a static functions. As you said they can be called explicitly by referring through object like:
MyObject.MyFunc1();
So which one to use depends on situation you're handling.

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

JavaScript library pattern

I'm trying to figure out the basic pattern for creating a JavaScript library (class). I want to do it in such a way that it doesn't pollute the global namespace with a bunch of junk, but allowing for the class to have instance variables and public methods that modify those instance variables.
Consider the following toy example. I want to make a class Foo. It should contain an instance member, bar, which is a number. There should be a constructor for Foo that takes a number and initializes its instance bar with that number. There should be an instance method that I can call on a Foo object to modify bar. Maybe the code that uses the library looks like this:
var foo1 = new Foo(1);
var foo2 = new Foo(2);
console.log(foo1.bar); // should print "1"
console.log(foo2.bar); // should print "2"
foo2.changeBar(42);
console.log(foo1.bar); // should print "1"
console.log(foo2.bar); // should print "42"
The resultant foo.js would be used by a Web app and therefore included via a script tag in the HTML.
I've done a bit of searching with Google but I have yet to find a single, concise, generic outline of how to design a JavaScript class (used as a library).
(function () {
Foo = function (num) {
this.changeBar(num);
};
var privateMethod = function (x) {
if (this.bar === 999) {
this.bar = x;
}
};
Foo.prototype.changeBar = function (num) {
this.bar = num;
privateMethod.call(this, 1);
};
}());
That is the simplest way of doing it. You don't need to include the definition in a closure, more of a style thing.
Building up on Evan's answer, to showcase some more possibilites. Most normal cases only use some of these though.
(function() {
//When we create variables inside a function they can only be seen by other
// inner functions. Wraping all our code here makes sure noone gets to see
// the private stuff.
//The first opening parenthesis is required for Javascript to parse it
//correctly though
//this is the constructor function
//Note how we set a global variable (Foo) to make it available outside.
Foo = function(num, another_num) {
this.changeBar(num);
//sometimes you will want to make a method that modifies a variable
//that can't be acessed via this.xxx. You can use a closure here for that
//(there are some performance considerations though)
this.baz = function(){
console.log(another_num);
}
//Setting methods "by hand" like this is also useful if you want to
//do multiple inheritance, since you can just set all methods of the
//second class by hand here if you want.
}
//Things on Foo.prototype will be available for all Foo objects,
// via prototypal inheritance magic.
Foo.prototype.changeBar = function(num) {
this.bar = num;
}
var a_secret_variable = 42;
function my_private_function(){
console.log(a_secret_variable);
}
//All private variables can be normaly used (by functions that can see them).
Foo.prototype.use_magic = function(){
my_private_function();
}
}());
//The "fake" function is imediatelly called,
//so in the end all it does is create a inner scope.
The Module Pattern is probably the most popular pattern used today.
var Foo = (function() {
var _thisIsAPrivateVar;
function thisIsAPrivateMethod() {
}
return {
thisIsAPublicMethod : function() {
// can still access the "private" variable and method
}
};
})();

Categories

Resources