Difference between nameFunction() {} and nameFunction () => {} in ECMA6 - javascript

I'm start learning Vue.js and ECMA6 syntax, I saw this in the tutorial:
methods: {
someMethod: function() {
console.log(this) // this works
}
}
Then I thought the syntax could be:
methods: {
someMethod: () => {
console.log(this) // this undefined
}
}
but this works:
methods: {
someMethod () {
console.log(this) // this works
}
}
Can explain the difference and the ECMA5 syntax?

Of your three options, only the first one is supported in ES5. The other two are additions in ES6.
The third option is an ES6 shortcut for the first option and thus they work identically in ES6.
When you use the arrow syntax as in the second one, this is NOT set to be the host object as it is in your first and third. That's one of the features of the arrow syntax and thus it should not be used when you expect this to be set to the host object. Instead, this will be set to the lexical context from where the code was defined - often referred to as "the value of this in the enclosing context" or the "lexical value of this" which in your case would be whatever this was when the host object was initially declared which apparently was undefined.
Here's a good reference article on arrow functions: ES6 In Depth: Arrow functions

Object methods that has method someMethod. In this case this is a link to object methods.
Object methods that has property someMethod that stores some anonymous function. In this function this is undefined because function is anonymous.
Object methods has internal function someMethod. In this function this is link to methods, because it's internal named function (not anonymous or external) of this object.
Good luck!
+ Try this way
var methods1 = function() {
var self = {
someMethod: function() {
console.log(self);
}
};
return self;
}();
var methods2 = function() {
var self = {
someMethod: () => {
console.log(self);
}
};
return self;
}();
var methods3 = function() {
function someOtherMethod() {
console.log(self);
}
var self = {
someMethod: function() {
someOtherMethod();
}
}
return self;
}();
methods1.someMethod();
methods2.someMethod();
methods3.someMethod();

Related

How to pass down function with "this" keyword [duplicate]

I have a question concerning how the "this" pointer is treated in a nested function scenario.
Say I insert this following sample code into a web page. I get an error when I call the nested function "doSomeEffects()". I checked in Firebug and it indicates that when I am in that nested function, the "this" pointer is actually pointing to the global "window" object - which I did not expect. I must not be understanding something correctly because I thought since I declared the nested function within a function of the object, it should have "local" scope in relation to the function (i.e. the "this" pointer would be referring to the object itself like how it is in my first "if" statement).
Any pointers (no pun intended) would be appreciated.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
In JavaScript the this object is really based on how you make your function calls.
In general there are three ways to setup the this object:
someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
In all of the above examples the this object will be someThing.
Calling a function without a leading parent object will generally get you the global object which in most browsers means the window object.
Since this appears to be among the most upvoted questions of its kind, let me add, after all these years, the ES6 solution using arrow functions:
var std_obj = {
...
displayMe() {
...
var doSomeEffects = () => {
^^^^^^^ ARROW FUNCTION
// In an arrow function, the 'this' pointer is interpreted lexically,
// so it will refer to the object as desired.
if (this.activeEffect=="fade") { }
};
...
}
};
this is not part of the closure scope, it can be thought of as an additional parameter to the function that is bound at the call site. If the method is not called as a method then the global object is passed as this. In the browser, the global object is identical to window. For example, consider the following funciton,
function someFunction() {
}
and the following object,
var obj = { someFunction: someFunction };
If you call the function using method syntax such as,
obj.someFunciton();
then this is bound to obj.
If you call someFunction() directly, such as,
someFunction();
then this is bound to the global object, that is window.
The most common work around is to capture this into the closure such as,
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var that = this;
var doSomeEffects = function() {
// the 'this' pointer is referring to global
// that, however, refers to the outscope this
if (that.activeEffect=="fade") { }
}
doSomeEffects();
}
To understand this question , try to get the output for the following snippet
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
myObject.func();
The above code will output the following to the console:
outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
In the outer function, both this and self refer to myObject and therefore both can properly reference and access foo.
In the inner function, though, this no longer refers to myObject. As a result, this.foo is undefined in the inner function, whereas the reference to the local variable self remains in scope and is accessible there. (Prior to ECMA 5, this in the inner function would refer to the global window object; whereas, as of ECMA 5, this in the inner function would be undefined.)
There's a difference between enclosure variables and "this". "this" is actually defined by the invoker of the function, while explicit variables remain intact inside the function declaration block known as the enclosure. See the example below:
function myFirstObject(){
var _this = this;
this.name = "myFirstObject";
this.getName = function(){
console.log("_this.name = " + _this.name + " this.name = " + this.name);
}
}
function mySecondObject(){
var _this = this;
this.name = "mySecondObject";
var firstObject = new myFirstObject();
this.getName = firstObject.getName
}
var secondObject = new mySecondObject();
secondObject.getName();
you can try it out here:
http://jsfiddle.net/kSTBy/
What's happening in your function is "doSomeEffects()", is being called explicitly, this means context or the "this" of the function is the window. if "doSomeEffects" was a prototype method e.g. this.doSomeEffects on say "myObject", then myObject.doSomeEffects() would cause "this" to be "myObject".
As explained by Kyle, you could use call or apply to specify this within the function:
Here is that concept applied to your code:
var std_obj = {
options: {
rows: 0,
cols: 0
},
activeEffect: "none",
displayMe: function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect == "fade") {}
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect == "fade") {}
}
doSomeEffects.apply(this,[]);
}
};
std_obj.displayMe();
JsFiddle
Since it wasn't mentioned I will mention that using .bind() is a solution -
doSomeEffects=doSomeEffect.bind(this);
doSomeEffects();
}
};
std_obj.displayMe();
Here is a more simple example -
bad = {
name:'NAME',
z : function() {
function x() { console.log(this.name); };
x()
}
};
bad.z() // prints 'undefined'
good = {
name:'NAME',
z : function() {
function x() { console.log(this.name); };
x=x.bind(this);
x();
}
};
good.z() // prints 'NAME'
It is true that using an arrow function => looks slicker and is easy for the programmer. However, it should be kept in mind that a lexical scope is likely to require more work in terms of processing and memory to setup and maintain that lexical scope, compared to simply associating a function's this with a pointer via .bind().
Part of the benefit of developing classes in JS was to provide a method to make this more reliably present and available, to pivot away from functional programming and lexical scopes, and thus reduce overhead.
From MDN
Performance considerations
It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.
It's because "this" refers to the self object / local function.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
if (this.activeEffect=="fade") { }
let This = this; // 'this' here is for the std_obj scope. Create a reference to 'this' if you want to use it elsewhere.
var doSomeEffects = function() {
// 'this' here refers to the doSomeEffects scope. If you don't want "this," you can still use "this" of the std_obj scope.
if (This.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
I also got a warning "Potentially invalid reference access to a class field via this"
class MyListItem {
constructor(labelPrm) {
this._flagActive = false;
this._myLabel = labelPrm;
labelPrm.addEventListener('click', ()=>{ this.onDropdownListsElementClick();}, false);
}
get myLabel() {
return this._myLabel
}
get flagActive(){
return this._flagActive;
}
onDropdownListsElementClick(){console.log("Now'this'refers to the MyListItem itself")}}//end of the class

`this` inside inner functions [duplicate]

I have a question concerning how the "this" pointer is treated in a nested function scenario.
Say I insert this following sample code into a web page. I get an error when I call the nested function "doSomeEffects()". I checked in Firebug and it indicates that when I am in that nested function, the "this" pointer is actually pointing to the global "window" object - which I did not expect. I must not be understanding something correctly because I thought since I declared the nested function within a function of the object, it should have "local" scope in relation to the function (i.e. the "this" pointer would be referring to the object itself like how it is in my first "if" statement).
Any pointers (no pun intended) would be appreciated.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
In JavaScript the this object is really based on how you make your function calls.
In general there are three ways to setup the this object:
someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
In all of the above examples the this object will be someThing.
Calling a function without a leading parent object will generally get you the global object which in most browsers means the window object.
Since this appears to be among the most upvoted questions of its kind, let me add, after all these years, the ES6 solution using arrow functions:
var std_obj = {
...
displayMe() {
...
var doSomeEffects = () => {
^^^^^^^ ARROW FUNCTION
// In an arrow function, the 'this' pointer is interpreted lexically,
// so it will refer to the object as desired.
if (this.activeEffect=="fade") { }
};
...
}
};
this is not part of the closure scope, it can be thought of as an additional parameter to the function that is bound at the call site. If the method is not called as a method then the global object is passed as this. In the browser, the global object is identical to window. For example, consider the following funciton,
function someFunction() {
}
and the following object,
var obj = { someFunction: someFunction };
If you call the function using method syntax such as,
obj.someFunciton();
then this is bound to obj.
If you call someFunction() directly, such as,
someFunction();
then this is bound to the global object, that is window.
The most common work around is to capture this into the closure such as,
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var that = this;
var doSomeEffects = function() {
// the 'this' pointer is referring to global
// that, however, refers to the outscope this
if (that.activeEffect=="fade") { }
}
doSomeEffects();
}
To understand this question , try to get the output for the following snippet
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
myObject.func();
The above code will output the following to the console:
outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
In the outer function, both this and self refer to myObject and therefore both can properly reference and access foo.
In the inner function, though, this no longer refers to myObject. As a result, this.foo is undefined in the inner function, whereas the reference to the local variable self remains in scope and is accessible there. (Prior to ECMA 5, this in the inner function would refer to the global window object; whereas, as of ECMA 5, this in the inner function would be undefined.)
There's a difference between enclosure variables and "this". "this" is actually defined by the invoker of the function, while explicit variables remain intact inside the function declaration block known as the enclosure. See the example below:
function myFirstObject(){
var _this = this;
this.name = "myFirstObject";
this.getName = function(){
console.log("_this.name = " + _this.name + " this.name = " + this.name);
}
}
function mySecondObject(){
var _this = this;
this.name = "mySecondObject";
var firstObject = new myFirstObject();
this.getName = firstObject.getName
}
var secondObject = new mySecondObject();
secondObject.getName();
you can try it out here:
http://jsfiddle.net/kSTBy/
What's happening in your function is "doSomeEffects()", is being called explicitly, this means context or the "this" of the function is the window. if "doSomeEffects" was a prototype method e.g. this.doSomeEffects on say "myObject", then myObject.doSomeEffects() would cause "this" to be "myObject".
As explained by Kyle, you could use call or apply to specify this within the function:
Here is that concept applied to your code:
var std_obj = {
options: {
rows: 0,
cols: 0
},
activeEffect: "none",
displayMe: function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect == "fade") {}
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect == "fade") {}
}
doSomeEffects.apply(this,[]);
}
};
std_obj.displayMe();
JsFiddle
Since it wasn't mentioned I will mention that using .bind() is a solution -
doSomeEffects=doSomeEffect.bind(this);
doSomeEffects();
}
};
std_obj.displayMe();
Here is a more simple example -
bad = {
name:'NAME',
z : function() {
function x() { console.log(this.name); };
x()
}
};
bad.z() // prints 'undefined'
good = {
name:'NAME',
z : function() {
function x() { console.log(this.name); };
x=x.bind(this);
x();
}
};
good.z() // prints 'NAME'
It is true that using an arrow function => looks slicker and is easy for the programmer. However, it should be kept in mind that a lexical scope is likely to require more work in terms of processing and memory to setup and maintain that lexical scope, compared to simply associating a function's this with a pointer via .bind().
Part of the benefit of developing classes in JS was to provide a method to make this more reliably present and available, to pivot away from functional programming and lexical scopes, and thus reduce overhead.
From MDN
Performance considerations
It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.
It's because "this" refers to the self object / local function.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
if (this.activeEffect=="fade") { }
let This = this; // 'this' here is for the std_obj scope. Create a reference to 'this' if you want to use it elsewhere.
var doSomeEffects = function() {
// 'this' here refers to the doSomeEffects scope. If you don't want "this," you can still use "this" of the std_obj scope.
if (This.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
I also got a warning "Potentially invalid reference access to a class field via this"
class MyListItem {
constructor(labelPrm) {
this._flagActive = false;
this._myLabel = labelPrm;
labelPrm.addEventListener('click', ()=>{ this.onDropdownListsElementClick();}, false);
}
get myLabel() {
return this._myLabel
}
get flagActive(){
return this._flagActive;
}
onDropdownListsElementClick(){console.log("Now'this'refers to the MyListItem itself")}}//end of the class

Can I set a local var to 'this' to reference it inside an anonymous callback function?

I would like to reference 'this' in a callback function, but there is no guarantee that 'this' will refer to the correct object. Is it appropriate to create a local variable referencing 'this' and use that variable inside the anonymous function?
Example:
var MyClass = function (property) {
this.property = property;
someAsynchronousFunction(property, function (result) {
this.otherProperty = result; // 'this' could be wrong
});
};
The problem is, the asynchronous function may call the provided callback from an arbitrary context (which is often outside of my control, e.g. when using libraries).
My proposed solution is:
var MyClass = function (property) {
this.property = property;
var myClass = this;
someAsynchronousFunction(property, function (result) {
myClass.otherProperty = result; // references the right 'this'
});
};
But I was looking to see if there are other strategies, or if this solution is problematic in any way.
What you've done is the classical way of making sure you refer to the correct object, though you should define it locally, i.e.:
function(property) {
var that = this;
someFunc(function(result) {
that.property = whatever;
}
}
Alternatively, in modern browsers you can bind it explicitly:
someFunc(function(result) {
this.property = whatever;
}.bind(this));
See also: bind()
Libraries such as jQuery support the latter functionality as a proxy function that more browsers support and can be simplified into this reusable function:
function proxy(fn, ctx)
{
return function() {
return fn.apply(ctx, arguments);
}
}
And to use it:
someFunc(proxy(function(result) {
this.property = whatever;
}, this));
Yes, that's fine, but don't use an implicit global variable as you did, use a local variable:
var myClass = this;

Prototype Pattern and "this"

I'm trying to create a client-side api for a web control using the Prototype pattern. However I want to make life easier by not having to manage "this".
This is some sample code (i have commented the problematic line):
MyObject = function ()
{
MyObject.initializeBase(this);
this._someProperty = null;
};
MyObject.prototype = {
initialize: function()
{
// Init
},
get_someProperty: function()
{
return this._someProperty;
},
set_someProperty: function(value)
{
this._someProperty = value;
},
doSomething: function ()
{
$('.some-class').each(function ()
{
$(this).click(this.doClick); // this.doClick is wrong
});
},
doClick: function ()
{
alert('Hello World');
}
};
Normally, using the revealing module pattern I would declare a private variable:
var that = this;
Can I do something similar with the Prototype pattern?
You can do the exact same thing you are used to, just do it within the doSomething method:
doSomething: function ()
{
var instance = this;
$('.some-class').each(function ()
{
$(this).click(instance.doClick);
});
},
This approach has nothing to with prototype or not, it's just how to manage context with nested functions. So when a function on a prototype (method) has nested functions within in, you may have to preserve the context this at any of those level if you want to access it in a nested scope.
ES5's Function.prototype.bind() might be an option for you. You could go like
doSomething: function ()
{
$('.some-class').each(function(_, node)
{
$(node).click(this.doClick); // this.doClick is right
}.bind(this));
},
Now, we proxied each event handler by invoking .bind() and as a result, we call it in the context of the prototype object. The caveat here is, you no longer have this referencing the actuall DOM node, so we need to use the passed in arguments from jQuery instead.

Best way to define a function?

I'm always learned to define a function in JavaScript like this:
function myFunction(arg1, arg2) { ... }
However, I was just reading Google's guide to Javascript, it mentioned I should define methods like this:
Foo.prototype.bar = function() { ... };
Question: Is "Foo" in the example an Object, or is it a namespace? Why isn't the Google example the following code (which doesn't work):
prototype.bar = function() { ... };
UPDATE: In case it helps to know, all of my JavaScript will be called by the users browser for my web-application.
Your two examples are not functionally equivalent. The first example simply defines a function (probably a global one, unless you define it inside another function). The second example extends the prototype of a constructor. Think of it as adding a method to the class Foo.
Unless you're building a JavaScript library, my suggestion would be to use neither and use some kind of namespace system. Create a single global object that acts as a namespace through which you can access all your functions.
var MyObject = {
utils: {
someUtil: function() {},
anotherUtil: function() {}
},
animation: {
// A function that animates something?
animate: function(element) {}
}
};
Then:
// Assuming jQuery, but insert whatever library here
$('.someClass').click(function() {
MyObject.animation.animate(this);
});
If you want to emulate classes in JavaScript, you would define the "class" as a function (the function itself being the constructor) and then add methods through the prototype property.
function Foo() {
// This is the constructor--initialize any properties
this.a = 5;
}
// Add methods to the newly defined "class"
Foo.prototype = {
doSomething: function() { /*...*/ },
doSomethingElse: function() { /*...*/ }
};
Then:
var bar = new Foo();
console.log(bar.a); // 5
bar.doSomething();
// etc...
I'm always learned to define a function in JavaScript like this:
function myFunction(arg1, arg2) { ... }
There are two ways to define a function. Either as a function declaration
function foo(...) {
...
}
Or as a function expression
var foo = function() {
...
};
Read more here.
However, I was just reading Google's guide to Javascript, it mentioned I should define methods like this: Foo.prototype.bar = function() { ... };
This is specifically related to method creation for objects, not just normal, stand-alone functions. Assuming you have the base object declaration:
var Foo = function() {
...
};
Just like any other assignment, to assign a function to an object's property, you must use an assignment expression. You can do this two ways. The succinct and common way (as suggested by Google's reference)
Foo.prototype.bar = function() {};
Or, if you want to continue to use the declarative form of defining functions
function bar() {
...
};
Foo.prototype.bar = bar;
This is normally more verbose than necessary, but may be useful in situations where you want to assign the same method to multiple object prototypes.
Question: Is "Foo" in the example an Object, or is it a namespace? Why isn't the Google example the following code (which doesn't work): prototype.bar = function() { ... };
Foo is an object. Although the concept can be expressed through the use of static objects, as I've shown in my answer to your other question, there is no such thing as namespaces in JavaScript. Further, especially in the example code given, Foo is likely intended to be an instantiated object, which precludes it from being behaving like a namespace.
Of course it doesn't work: prototype has not been defined as an object (unless, of course, you define it as such). The prototype property exists on every object (a function is also an object), which is why you can do Foo.prototype.bar = ...;. Read more here.
=====> 2017 Update <=====
This question and answers is 7 years old and is very outdated. This answer includes new syntax for versions of ES5, ES6, and compatible with ES7.
Best way to define a function?
There is no one "Best" way to define a function. How you define the function is dependent on the intended use and lifetime of the function.
Global functions
Defined as a statement with the function token followed by the function name with lowercase camelcase
function functionName (arguments) {
// function body
}
is preferable over the function expression...
var functionName = function (arguments) {
// function body
}
...as the assignment to the variable of the function does not occur until the defining line is executed. Unlike the prefered method which is available immediately after parsing before any code is executed.
const functionName = function(arguments){/*function body*/}
var functionName = function functionName(arguments){/*function body*/}
var functionName = function functionAltName(arguments){/*function body*/}
Function objects
As a function statement with uppercase camelcase function name
function MyObjectFunction (arguments) {
/*function body*/
// if this function is called with the new token
// then it exits with the equivalent return this;
}
const obj = new MyObjectFunction(foo);
Anonymous function expression.
A common practice is to create object via an immediately invoked function that has no name (and is hence anonymous)
;(function (arguments) { /*function body*/ } ("argument val"))
Or
;(function(arguments){ /*function body*/ })("argument val")
NOTE the inclusion of the ; befor the function. This is very important as the open "(" will prevent automatic semicolon insertion on any code above the function.
Immediately invoked function expression.
const functionResult = (function (arguments) {
/*function body*/
return functionResult;
}());
const functionResult = (function (arguments) {
/*function body*/
return functionResult;
})();
As a var or block scopedconst, let
Anonymous callback.
With ES6 you should use the arrow function syntax rather than anonymous function expressions.
myArray.forEach((item,i) => {/*function body*/});
myArray.filter(item => !item);
setTimeout(() => {/*function body*/}, 1000);
Function as properties.
Using the object declaration function shorthand syntax.
var myObj = {
functionName (arguments) {/*function body*/},
}
// called
myObj.functionName("arg");
is preferable over
var myObj = {
functionName : function (arguments) {/*function body*/},
}
Or via function object declarations
function MyObjectFunction(arguments){
this.propertyFunction = function(arguments) { /*function body*/ }
// or arrow notation is fine
this.propertyFunction = (argument) => { /*function body*/ };
}
Functions as prototypes
function MyObj (arguments) {
MyObj.prototype.functionName = function(arguments) { /*function body*/ }
}
or
function MyObj (arguments) {}
MyObj.prototype.functionName = function(arguments) { /*function body*/ }
or
MyObj.prototype = {
functionName(arguments) { /*function body*/ }
}
Defining a prototype function is useful when creating constructors or 'classes' in JavaScript. e.g. a func that you will new
var MyClass = function(){};
MyClass.prototype.doFoo = function(arg){ bar(arg); }
but is of no use in plain old library functions e.g.
function doPopup(message){ /* create popup */};
There are several benefits of using a prototype function including but not limited to
speed
memory usage
extensibility
But, again, this is in the context of creating constructors for instantiable 'classes'
HTH
It works like so:
(function(){ // create an isolated scope
// My Object we created directly
var myObject = {
a: function(x,y) {
console.log('a');
},
b: function(x,y) {
console.log('b');
this.a(x,y);
}
};
})();
(function(){ // create an isolated scope
// Create a Object by using a Class + Constructor
var myClass = function(x,y) {
console.log('myClass: constructor');
this.b(x,y);
};
myClass.prototype = {
a: function(x,y) {
console.log('myClass: a');
},
b: function(x,y) {
console.log('myClass: b');
this.a(x,y);
}
};
// Define a function that should never inherit
myClass.c = function(x,y) {
console.log('myClass: c');
this.a(x,y);
};
// Create Object from Class
var myObject = new myClass();
// Will output:
// myClass: constructor
// myClass: b
// myClass: a
// Define a function that should never inherit
myObject.d = function(x,y) {
console.log('myObject: d');
this.a(x,y);
};
// Test the world is roung
console.log(typeof myClass.c, 'should be undefined...');
console.log(typeof myClass.d, 'should be function...');
})();
(function(){ // create an isolated scope
// If you are using a framework like jQuery, you can obtain inheritance like so
// Create a Object by using a Class + Constructor
var myClass = function(x,y) {
console.log('myClass: constructor');
this.b(x,y);
};
myClass.prototype = {
a: function(x,y) {
console.log('myClass: a');
},
b: function(x,y) {
console.log('myClass: b');
this.a(x,y);
}
};
// Create new Class that inherits
var myOtherClass = function(x,y) {
console.log('myOtherClass: constructor');
this.b(x,y);
};
$.extend(myOtherClass.prototype, myClass.prototype, {
b: function(x,y) {
console.log('myOtherClass: b');
this.a(x,y);
}
});
// Create Object from Class
var myOtherObject = new myOtherClass();
// Will output:
// myOtherClass: constructor
// myOtherClass: b
// myClass: a
})();
(function(){ // create an isolated scope
// Prototypes are useful for extending existing classes for the future
// Such that you can add methods and variables to say the String class
// To obtain more functionality
String.prototype.alert = function(){
alert(this);
};
"Hello, this will be alerted.".alert();
// Will alert:
// Hello, this will be alerted.
})();
Edit: Fixed code so that it will actually run in your browser if you copy and paste :-)
Foo is both an Object and a namespace. See this question.
Using objects as namespaces prevents name collisions. That's always a good idea, but especially when you're developing and/or using shared libraries.
If you don't expect to be making multiple Foo objects (and so don't need the object-oriented style), you could create your functions as methods on a singleton object:
var Foo = {}
Foo.bar = function() { ... }
or
var Foo = {
bar: function() {...},
quux: function() {...}
};
You'd then simply call the function as:
Foo.bar()
(This kind of declaration is roughly equivalent to a static method in C++ or Java.)

Categories