Javascript and Inheritance - javascript

Say I have a Class:
function Foo() {
this.foo1 = null;
this.foo2 = function() { return false;};
}
And I want other objects to inherit variables & functions from it.
function Bar(){}
function Baz(){}
Then instantiate my objects:
var bar = new Bar();
bar.foo1 // returns null
bar.foo2() // returns false
What's the proper function to include Foo in Bar and Baz?
I already did Bar.prototype = new Foo(); but it seems to fail on our beloved IE (<9).

If you attach all the properties to the prototype (which is preferable, at least for methods),
function Foo() {}
Foo.prototype.foo1 = null;
Foo.prototype.foo2 = function() { return false;};
then assigning the parent's prototype to the child's prototype is sufficient:
function inherit(Child, Parent) {
var Tmp = function(){};
Tmp.prototype = Parent.prototype;
Child.prototype = new Tmp();
Child.prototype.constructor = Child;
}
inherit(Bar, Foo);
Here we used an intermediate constructor function to "decouple" the two prototypes. Otherwise if you'd change one, you'd change the other one too (as they reference the same object). This way is actually pretty popular and used by a couple of libraries.
If not, you have to call the parent's constructor function inside the child's constructor function:
function Bar() {
Foo.call(this);
}
This is something you always should do, to assign the properties set up in the constructor function to the current object.
An additional remark to your way:
Bar.prototype = new Foo();
this should work (also in IE actually), but it has two major flaws:
All the instance properties set up in Foo will become properties shared by all Bar instances.
What if Foo expects some arguments that are only available when you create a Bar instance?

have a look to Classy or, if you like Ruby and want a more complete solution to JS.Class. Those libraries helps you with object orientation in javascript ad hide prototype to the developer.
Hope this helps

Related

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

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

Why does the __proto__ object evaluate to "Object" in the debugger?

I'm reading Kyle Simpson's "YDKJS: this & Object Prototypes", and looking at his example of behavior delegation. Here's the code below:
Foo = {
init: function(who) {
this.me = who;
},
identify: function() {
return "I am " + this.me;
}
};
Bar = Object.create( Foo );
Bar.speak = function() {
alert( "Hello, " + this.identify() + "." );
};
var b1 = Object.create( Bar );
b1.init( "b1" );
var b2 = Object.create( Bar );
b2.init( "b2" );
b1.speak();
b2.speak();
He uses this diagram to describe the relationships between these objects:
Now my question:
When tinkering with this code in Chrome Developer tools, I see that the __proto__ object evaluates to Object. Why is that? Shouldn't the __proto__ object depict the actual relationship in the diagram, where b1 and b2 delegate to Bar which in-turn delegates to Foo? Why are these relationships not explicitly named in the __proto__ object? After-all, this implementation uses the Object.create() method, and places an argument in the proto parameter (the first parameter). Wouldn't it be expected that the console would return that named argument as the value of the __proto__ object?
This isn't quite so simple. The __proto__ property is a dynamic link to the .constructor's prototype.
However, .constructor isn't overwritten in these cases (though it can be in certain hand-made libraries).
When you're looking for a reference to Foo to show up in that chain, it's a very "classical" viewpoint, and less to do with prototypal inheritance, which inherits from a concrete instance, rather than a class, and in the case of JS, references (when not scalar), rather than copies.
The tl;dr reason is simply: Object.create's constructor is Object, {}'s constructor is Object and Object.prototype's constructor is Object.
The Long Way
First thing to know:
names in these lookups aren't tied to variables, but rather they're tied to functions, typically.
Once upon a time, the field where this information could be found was hidden, and now it's found it's way to the .name property of a function (function Foo () { } Foo.name; //Foo) in many browsers now (much like __proto__ used to be invisible.
Second bit:
names which you see in console references, and in type-checks, aren't based on the proto, but on a property called .constructor.
// Equivalent assignments
var obj1 = { };
var obj2 = new Object();
var obj3 = Object.create(Object.prototype);
obj1.constructor; // Object
obj2.constructor; // Object
obj3.constructor; // Object
If we were to change the dynamic a little, and introduce the more "classical" approach to instance-creation, which is paseƩ, but will see a resurgence in ES6 with the class sugar...
function Foo () {
this.isFoo = true;
}
var foo = new Foo();
foo.isFoo; // true
foo.constructor; // Foo
foo.__proto__ === Foo.prototype; // true
foo.__proto__.constructor; // Object
That last little bit there is telling, for your immediate question; Foo.prototype is nothing but a plain ol' Object instance.
In the days of JS where everybody was looking for the best possible way of making JS feel like Java / C#, you'd see something like:
function Foo () { }
function Bar() { }
Bar.prototype = new Foo();
var foo = new Foo();
var bar = new Bar();
bar instanceof Bar; // true
bar instanceof Foo; // true
On one hand, this sort of works, as we've been able to reuse method's of Foo on instances of Bar.
Grand.
The immediate downside is that all instances of Bar share the same instance of Foo, including all of its instance-specific properties.
While this method is far from what I'd suggest as a pattern for reuse, it does show off your dilemma well.
// using the last set of assignments
bar instanceof Foo;
// equivalent to:
bar.constructor === Foo; // false
bar.__proto__.constructor === Foo; // true
// not equivalent to
bar.__proto__ == Foo;
More modern forms of "classical" inheritance (calling a super constructor, copying prototypes of other constructors onto your new constructor, etc) do a better job of allowing you to compose and reuse methods...
But that comes at the cost of being able to rely on the __proto__ chain for looking up where those loaned methods come from.
Historically, the "bad for reuse, good for type-checking" model let you search
val.__proto__.__proto__.__proto__.__proto__. (...) .__proto__.constructor
until it matched your instanceof, or until you hit Object at the end of the line.
Newer forms copy the values directly onto val.__proto__ (/ val.constructor.prototype, which we've seen is the same object, at creation of val), which means your proto chain runs out very quickly.

javascript .prototype for object function extensions

--
Hello SO,
Hoping for some minor guidance on the issue of .prototype.
I've gone through all the answers in SO and they did not seem to cover this specific question, or maybe they did but I did not understood it like that.
The question at hand (and code)
function foo(){};
foo.prototype.type = 'foo';
function bar()
{
this.prototype = foo.prototype;
}
test = new bar();
console.log(test.type); // type is undefined
The question
From what I understand, the request for the type had to cascade up the prototype chain until it found the foo prototype, This did not happen, Obviously I'm understanding something wrong - Why is type undefined?
I'm basically trying to find a way to extend a function object so that
new foo() - return a foo object
new bar() - return a bar object that has all the methods and properties of foo.
I appreciate any help or reference I can get!
Well, when you do this:
function bar()
{
this.prototype = foo.prototype;
}
you are not changing the bar object prototype but assigning a new property to the bar object called prototype, which has the foo object prototype, basically: { type: 'foo' }.
then:
test = new bar();
console.log(test.type); // type is undefined
of course is undefined! you never define it, you just define the prototype property
console.log(test.prototype); // I have surprises for you
I think you want somethink like inheritance. I suggest the Crockford way of inheritance:
Function.prototype.inherits = function (Parent) {
this.prototype = new Parent();
return this;
};
Then, just do:
bar.inherits(foo);
Now,
test = new bar();
console.log(test.type); // foo!
Hope this helps
Thanks for the comments and replies, to extend lante's answer to what I think is fully explaining the situation.
A JavaScript function is of course an object, When you instantiate a new instance of a function object, The created object receives the prototype of that function.
for instance,
var Foo = fn() {
this.ok= 'this is okay';
}
var Bar = fn(){};
Bar.prototype = new Foo(); // Bar.prototype is now a regular object, nothing fancy.
//for all intents and purposes, this is exactly like doing this :
Bar.prototype = {ok : 'this is okay'}; //just assigns an object, reduntent
var test = new Bar(); //new Bar instance
console.log(test.ok); //prints 'bar'
What's the magic?
test has no ok property, But when it's being called it chains up to the function object's prototype and tries to find it there, if it can't, it keeps moving up until it reaches the end.
Thanks again for all the answers

Is this a safe way of copying one objects prototype to another?

Say I have one object with prototypal properties that I have manually set.
An example would be
function A() {
};
A.prototype.B = function() {
};
A.prototype.C = function() {
};
A.prototype.D = function() {
};
How can I extend another object with A's prototype?
What I have tried is this;
// obj = extend to object
// obj2 inherit from object
for (var prop in obj2.prototype) {
if (obj2.prototype.hasOwnProperty(prop)) {
obj.prototype[prop] = obj2.prototype[prop];
}
}
Does using obj2.hasOwnProperty(prop) ensure that only the properties that are on A's prototype that I have will get copied?
Is there a better way of doing this?
Generally, it's not always advisable to try and emulate patterns from other languages into Javascript. Javascript uses prototypal inheritance, and not standard OO inheritance (such as what you do in Java). Yes, you can copy methods from one prototype to another, but it is not always advisable, because you're really blowing the encapsulation of the inner object out of the water. If you do want to copy methods, you can do so simply by setting one objects prototype equal to the other.
Here is one pattern for doing inheritance
// object we want to inherit from
function bar() {}
bar.prototype.original = function() {}
// object which will inherit bar
function foo() {}
// first map prototypes
foo.prototype = new bar();
// add additional methods to foo
foo.prototype.somethingElse = function() {}
Instead of doing new bar() you could do Object.create(bar), as some of the commenters have pointed out, but that is not supported in IE8 and below. The only functional difference between the two is that new bar() will execute the constructor of bar, while the latter will not, which may or may not matter to you. Object.create() is technically the more correct way to go, but can be a deal breaker unless you are willing to lose IE8 or use a shim.
Here is another pattern, my preferred, using composition instead
// object we want to inherit from
function bar() {}
bar.prototype.original = function() {}
function foo() {
this.bar = new bar();
}
foo.prototype.somethingElse = function() {
// foo has a bar, but isn't a bar
this.bar.original();
}

javascript function object's inherit method behaviour

I've come across a behaviour of the function object. that seems to be similar to prototyping but uses a different method.
var Car = function() {
this.foo = 'shiny';
}
var Rover = function() {
this.inherit = Car;
this.inherit();
}
var Mini = function() {
this.inherit = Car;
this.inherit();
}
when a new instance of a sub class is made this.inherit method has the effect of calling the parent class on itself, so that the parent's properties and methods are available to the sub class.
var myRover = new Rover();
var myMini = new Mini();
myMini.foo = 'rusty';
console.log(myRover.foo, myMini.foo); // displays "shiny" & "rusty" respectively
I've looked in Mozilla and MSDN, but I can't seem to find it documented any where. Can anyone put a name to this behaviour and any further documentation.
I think the word inheritFrom does not make any sense here. It could be as well bar. What makes this work is the pattern that you define a member of the "subClass" function which you call on the next line.
It may be worth checking out "Classical Inheritance in JavaScript" article by Douglas Crockford for some additional ideas.
inheritFrom isn't a method that exists in JavaScript core objects. JavaScript inheritance can be accomplished in many ways as outlined in this post. What you're doing here is not really proper inheritance as you're just setting a single method in a separate object equal to a function.
First you declare a function called superClass. This function sets the foo and bar properties of the this object. When you set a method on subClass equal to superClass the this object then references the subClass function because it is the method's caller so then subClass has the properties of foo and bar set to 'foo' and 'bar'.
However, when you overwrite the foo method here:
this.foo = function() {
return this.foo;
};
You turn foo into a function.
Notice that when you add this script:
var test = new subClass();
alert(test.foo);
test.foo will be a function as you overrode its value in the subClass constructor. Adding this:
alert(test.bar);
Will alert the string 'bar' since you didn't overwrite it. Also if you call test.foo() it will simply return a pointer to the test.foo method.

Categories

Resources