I'm using a classical javascript prototypal inheritance, like this:
function Foo() {}
Naknek.prototype = {
//Do something
};
var Foo = window.Foo = new Foo();
I want to know how I can improve this and why I can't use this model:
var Foo = window.Foo = new function() {
};
Foo.prototype = {
//Do something
};
Why this code doesn't work? In my head this is more logical than the classical prototypal inheritance.
Your var Foo = window.Foo = new Foo(); example is...odd. First you declare a function Foo, then you assign something to its prototype (I assume you meant to replace Nannak with Foo in your second line), and then you overwrite the reference to the function by assigning to it.
Standard Javascript prototypical inheritance looks like this:
// Create a constructor `Foo`
function Foo() {
}
// Give the prototype for `Foo` objects a function bound to the
// property `bar`
Foo.prototype.bar = function() {
}
// Only do this bit if you're doing this within a function and you want
// to make `Foo` available as a property of `window` (e.g., effectively
// a global variable. If this code is already at global scope, there's
// no need to do this.
window.Foo = Foo;
Here's how you'd use Foo:
// Create a `Foo` and use its `bar`
var f = new Foo();
f.bar();
A couple of other notes:
Never use new function() { ... } unless you really, really know what you're doing. It creates an object initialized by the function, it does not create a new function. There's almost never any need for the similar (but totally different) new Function(...), either, again except for some advanced edge cases.
The function bound to bar in my example above is anonymous (the property it's bound to has a name, but the function does not). I'm not a fan of anonymous functions, but I didn't want to clutter the example above. More here.
If you use var at global scope (it wasn't clear from your question whether you were), it creates a property on the window object. You'd only need to do var Foo = window.Foo = ... if you're within a function and want to both create a propety of window and create a local variable called Foo. (Which maybe you meant to do! :-) )
The Foo.prototype = { .. }; way of assigning prototypical properties works, but it's not generally a good idea (again, unless you're pretty up-to-speed on this stuff). When you do that, you're completely replacing the prototype object used when you call the function via new, whereas if you just add properties to it (Foo.prototype.bar = ...), you're just augmenting the prototype, not replacing it. Replacing the prototype is perfectly valid, but there are some non-obvious things that can happen if you're unwary. :-)
You are using the new operator on the function expression, that causes a newly created object to be assigned to window.Foo.
That new object is not a function, therefore it doesn't have a prototype property and it cannot be invoked.
"doesn't work" is vague, but I think the root cause is new function() { (new doesn't belong here)
You probably want:
var Foo = window.Foo = function() {
};
Foo.prototype = {
bar: 'baz'
};
alert(new Foo().bar); // baz
Related
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
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm getting stuck because of less understanding of prototypal inheritance. I want to know what is prototypal inheritance exactly and how it is implemented.
Could you please show one ease example?
Any help is appreciated.
At its core
Imagine you have an object and you want to look up a property. Now imagine the property doesn't exist. What if you could make it automatically continue the search for that property on a different object? That's basically what prototypal inheritance is.
How do we do it?
So then the only question is how to create this relationship between objects. Well, that's the weird part.
I'll start with the main, historical way of doing it. That is using functions.
First thing to note is that a function in JavaScript is itself an object. It can have its own properties, and it uses prototypal inheritance to gain access to other properties.
So let's start by creating a function.
function Foo() {
// our function
}
So now we have a function named Foo. Our new function automatically gets a property named prototype when it's created. That property references an (almost) empty object.
console.log(typeof Foo.prototype); // object
Why does that property and object exist? Well, they exist to support the weird way that JavaScript has formed that relationship between objects that I described above.
Basically, the Foo.prototype object is what we're going to use as the "backup" object when looking for new properties on our objects. But we still haven't formed any special relationship between the object we want to use, and the Foo.prototype object.
Putting it to work
To do that, we actually invoke the function using the new operator.
var my_object = new Foo();
And there we go. So now my_object is a new, empty object. But it has in its "prototype chain" that object that is dangling from our Foo function off of its .prototype property. In other words, when we look for a property on my_object, if the property doesn't exist, it'll continue the search on the Foo.prototype object.
See it in action
Trouble is that we haven't added anything that we might find useful to Foo.prototype. But there actually is one property on that object. That property was also automatically created when we made our Foo function, and it's the .constructor property.
What does that property reference? It has a reference back to the Foo function. In other words:
Foo.prototype.constructor === Foo; // true
Alright, so if our my_object is empty, and if when looking for a property on my_object that doesn't exist, it continues the search on the Foo.prototype object, then that should mean that we should be able to automatically get to the Foo.prototype.constructor property from my_object.
my_object.constructor === Foo; // true
And it works. Since my_object didn't have a property named constructor, it continued its search on the object from which it inherits, which is Foo.prototype, which as we know, has a .constructor property that refers to the Foo function.
Customizing for our code
Super. But how do we set up other properties that are more useful to us in our code? We just add them to Foo.prototype. That will let our my_object find those properties if the object doesn't own them directly.
// give a custom property to `Foo.prototype`
Foo.prototype.bar = "foobar";
// see if we can access that property on your object
my_object.bar === "foobar"; // true
Sure enough, it worked. So let's see if we can create a new object from Foo that also has access to that .bar property.
var another_object = new Foo();
another_object.bar === "foobar"; // true
Again, it works. This is because all objects created by invoking Foo using the new keyword will have in their prototype chain the Foo.prototype object. In other words, Foo.prototype is shared among all instances created from Foo.
So if we now modify the Foo.prototype.bar property, it will be reflected in both objects we created.
Foo.prototype.bar = "raboof";
my_object.bar === "raboof"; // true
another_object.bar === "raboof"; // true
So we can see that both of our objects are simply looking for properties that they don't have by passing the search on to the next object in their "prototype chain", which is that weird object dangling off the Foo function... Foo.prototype.
There's more to learn
There are newer ways to set up this object relationship, but this is the original way, and in spite of its weirdness, should probably be understood first.
This is how I understand it:
This could be considered a constructor
var Thing = function(){
this.method1 = function(){
alert( "method 1" );
}
}
This is an instance of it
var a_thing = new Thing();
a_thing.method1();
Now, if you add something to the prototype of the constructor, it is automatically available to the already instantiated object.
Thing.prototype.method2 = function(){
alert( "method2" );
}
a_thing.method2();
Hope this helps.
This is the simplest example I can think of,
pizza class inherits from circle by using this line:
pizza.prototype = new circle();
Full example:
<html>
<head>
<script>
// base class
function circle(radius){
this.radius = radius;
this.getArea = function ()
{
return (this.radius * this.radius) * Math.PI;
};
this.foo = function ()
{
return "circle foo";
};
return true;
}
// child class
function pizza(flavour, radius){
circle.call(this, radius);
this.flavour = flavour;
this.foo = function ()
{
return "pizza foo";
};
return true;
}
// Inheritance
pizza.prototype = new circle();
function Go(){
// Instancing new object
var myCircle = new circle(8);
var myPizza = new pizza("Onion", 5);
// Calling property
var pizza_area = myPizza.getArea();
// Calling override foo function
var foo = myPizza.foo();
// Calling foo base class
var base = pizza.prototype.foo.call(myPizza);
//Line.prototype.someFunction.call(myLine);
var isBase = myCircle instanceof pizza;
isBase = myPizza instanceof pizza;
}
</script>
</head>
<body onload="Go();">
</body>
</html>
In the example below I noticed the comment "fixes the delegated constructor reference" and I'm curious -how can I show this "not working / then working after I add that line of javascript?
full gist here => https://gist.github.com/getify/5572383
Thank you in advance
function Foo(who) {
this.me = who;
}
Foo.prototype.identify = function() {
return "I am " + this.me;
};
function Bar(who) {
Foo.call(this,"Bar:" + who);
}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.constructor = Bar; // "fixes" the delegated `constructor` reference
Functions in javascript are actually objects. When we create any function Foo in Javascript, the interpreter automatically creates a prototype property Foo.prototype, which is itself an object. The interpreter then creates a constructor property on this object which refers to Foo itself:
console.log(Foo.prototype.constructor); // reference to Foo;
console.log(Foo.prototype.hasOwnProperty("constructor")); // TRUE;
This same process takes place when we create the Bar function. But later we introduce a difference. The difference is that we manually overwrite the object at Bar.prototype with this code:
Bar.prototype = Object.create(Foo.prototype);
Now Bar.prototype has a new object that we created manually. This new object does not have a constructor property because it was created by us and not the interpreter:
console.log(Bar.prototype.hasOwnProperty("constructor")); // FALSE
So Bar.prototype does not have its own constructor property but Foo.prototype does. Next, imagine that we create an instance of Bar:
var myBar = new Bar();
myBar.constructor is an inherited property that does not exist on the myBar object. If we try to access it, the javascript interpreter searches up the prototype chain for the constructor property. It does not find one on Bar.prototype because we overwrote that object. The interpreter continues searching and eventually finds the property on Foo.prototype. As a result, any reference to myBar.constructor will refer to Foo.prototype.constructor, which contains a reference to Foo:
console.log(myBar.constructor); // reference to Foo
So this is why we explicitly set Bar.prototype.constructor manually, so that when traversing the prototype chain, the interpreter will find a constructor property on Bar.prototype as it would have if we hadn't overwritten it:
Bar.prototype.constructor = Bar;
The end result is more useful behavior on our objects:
var myBar2 = new Bar();
console.log(myBar2.constructor); // reference to Bar
This issue should not come up often as it is somewhat rare that one would need to check the constructor property of an object.
I am trying to duplicate private prototype methods in javascript and found this bit of code, but I do not fully understand how it implements itself.
The code is...
var Foo = function () {};
Foo.prototype = (function () {
// Private attributes
var somePrivateAttribute = 'Hello world';
// Private methods
function somePrivateMethod(val) {
alert(val);
}
// Public attributes and methods
return {
somePublicMethod: function () {
somePrivateMethod(somePrivateAttribute);
}
};
})();
What I do not understand is when this object is initiated new Foo() does that create a new object for the prototype every time as it is in a self executing function? Could anyone please explain the benefits and disadvantages of using this for a project of mine.
How would this type of pattern work for objects that could have 500 instances or just 1. I am trying to understand and would greatly appreciate if anyone could enlighten me?
Is there any performance benefits to using this method?
What I do not understand is when this object is initiated new Foo() does that create a new object for the prototype every time as it is in a self executing function?
No. That's the point of prototypes, they are not duplicated - every of your Foo instances will inherit from the same Foo.prototype object.
Could anyone please explain the benefits and disadvantages of using this for a project of mine.
It looks like you're having a little misunderstanding, regarding the naming: Those "private" things are no "attributes" or "methods", as they have absolutely nothing to do with instance objects. They are just local variables which are only accessible from the functions you assign to the prototype object.
You might want to read How do JavaScript closures work? and their use in IIFEs.
How would this type of pattern work for objects that could have 500 instances or just 1.
It's perfectly fine. However, using the constructor pattern for just 1 instance might be a little odd - singletons can be defined in a simpler way.
If you want to read more on that pattern, search for revealing prototype pattern - it's the revealing module pattern applied to create prototype objects.
I haven't seen that pattern before, using a module (that's what it's called) for the prototype... but here's what I'd recommend; it's similar but the module encloses everything:
var Foo = (function FooClass() {
var privateVar = 'Hello world';
function privateFunc() {
...
}
function Foo() {}
Foo.prototype = {
publicMethod: function() {
...
}
};
return Foo;
}());
var foo = new Foo();
What I do not understand is when this object is initiated new Foo()
does that create a new object for the prototype every time as it is in
a self executing function?
The self executing function runs once, returns the object, and it won't run again; it keeps a reference to the variables via closure.
What I do not understand is when this object is initiated new Foo() does that create a new object for the prototype every time as it is in a self executing function?
No, the assignment to Foo's prototype only happens once. Nothing wrong with it at all, just a little unconventional.
You could also write it like this (also unconventional, but accomplishes the same thing):
var Foo = function () {};
Foo.prototype = new function() {
// Private attributes
var somePrivateAttribute = 'Hello world';
// Private methods
function somePrivateMethod(val) {
alert(val);
}
// Public attributes and methods
this.constructor = Foo;
this.somePublicMethod = function () {
somePrivateMethod(somePrivateAttribute);
}
};
As Bergi pointed out, this adds an extra object to the prototype chain; if you want to avoid that, you can write it like this instead:
var Foo = function () {};
(function() {
// Private attributes
var somePrivateAttribute = 'Hello world';
// Private methods
function somePrivateMethod(val) {
alert(val);
}
// Public attributes and methods
this.somePublicMethod = function () {
somePrivateMethod(somePrivateAttribute);
}
}).call(Foo.prototype)
By modifying the prototype instead of replacing it, the constructor property also stays intact.
example = {};
example.Math = {
sin: function() {console.log('sin');},
cos: function() {console.log('cos');}
};
foo = function(){
sin();
};
foo.prototype = window.example.Math;
console.log(foo.prototype)
console.log(foo.cos)
console.log(foo())
http://jsfiddle.net/Mubqy/9/
From what I thought I understood references are searched for through the scope chain. So theoretically if I assign an object with functions defined to a prototype I should get all of those functions and fields of the object or so I thought. Where is the error in my understanding? Neither of the above scenarios work. Additionally the internal proto variable is not being updated. Obviously that's why it is not working, but why doesn't my assignment to the prototype work?
I think you need to realize that the prototyped method needs to be run with the new keyword, and it needs to use this to access its variables and methods, like this:
example = {};
example.Math = {
sin: function() {console.log('sin');},
cos: function() {console.log('cos');}
};
foo = function(){
this.sin();
};
foo.prototype = window.example.Math;
console.log(foo.prototype)
console.log(foo.cos)
console.log(new foo())
You missed two very crucial aspects of prototype.
A prototype acts as the parent of the object
You must initiate an instance of your object
First, use the keyword this to access object's methods and variables:
var foo = function(){
this.sin();
};
Than initiate an instance of the object using the keyword new:
new foo();
Just like OOP, only not :)
http://jsfiddle.net/46fPe/