I was wondering how one would go about making "classes" similar to those in Python in Javascript. Take the Python classes and functions listed here:
class one:
def foo(bar):
# some code
The function "foo" would be called with one.foo(bar).
What would the JS equivalent be? I suspect it would be something like this:
var one = {
foo: function(bar) {
// JavaScript
}
};
Thanks.
The native way to create classes in Javascript is to first define the constructor:
function MyClass() {
}
and a prototype:
MyClass.prototype = {
property: 1,
foo: function(bar) {
}
};
Then you can create instance of MyClass:
var object = new MyClass;
object.foo();
Add static methods:
MyClass.staticMethod = function() {};
MyClass.staticMethod();
Extend MyClass:
function SubClass() {
}
SubClass.prototype = new MyClass;
SubClass.prototype.bar = function() {
};
var object = new SubClass;
object.foo();
object.bar();
Classy is a JavaScript library that tries to bring Python-like classes to JavaScript.
Have a look at this link. There a different ways to do OO programming in Javascript. The details are too much to be explained here.
If you are serious about Javascript programming, you should read this book.
If you want to do real heavy OO programming, I would recommend to have a look at Coffee Script.
Javascript doesn't really have classes. What it has is prototypes -- an instance of an object that is used as a template for new objects.
The way you've created your object is to use a literal constructor. It's succinct, but suffers that it cannot be added to or use complicated statements in its construction.
Another way is like so:
function SomeClass(value) {
if (value < 0) {
this.field = -1;
} else {
this.field = value;
}
}
And a new instance is created like this:
var obj = new SomeClass(15);
This enables you to use conditional logic, for loops and other more complicated programming techniques in construction of your object. However, we can only add instance fields and not 'class' fields. You add class fields my modifying the prototype of your object creator function.
MyClass.prototype.fieldSquared = function () {
return this.field * this.field;
}
This gives a more complete overview of object creation and prototypes in Javascript.
Related
I'm trying to figure out how to construct my Javascript classes (or singleton objects) correctly.
var obj = new Object();
obj.foo = 'bar';
obj.method = function() { ...}
var obj = {
foo : 'bar',
method : function() { ...}
}
var obj = function(){}
obj.prototype = {
foo : 'bar',
method: function() { ... }
}
I want to be able to set a couple of properties and assign the methods available. I would also like to be able to use things like mixins on the objects so I can extend these objects with things like events.
I'm trying to figure out how to construct my Javascript classes (or singleton objects) correctly.
There's a big difference between those ("classes" and singleton objects). Your first couple of examples are one-off objects (singletons). Your third (last) example creates a constructor function that will allow you to create multiple objects sharing the same prototype. I would recommend augmenting the prototype property on the constructor function rather than replacing it as you're doing, e.g.:
var Thingy = function() { // Or use a function declaration rather than expression
// Optional initialization code here
};
Thingy.prototype.foo = 'bar';
Thingy.prototype.method = function() {
// Method code here
};
(Constructor functions, by convention, start with an upper case letter.)
Which you use (singleton or constructor function) depends on what you need.
As of ES2015 (aka "ES6"), it's simpler, although there's no new syntax for defining a non-method prototype property (your foo); there probably will be in ES2017 or ES2018, once this proposal moves forward, but until then:
class Thingy {
constructor() {
// Optional initialization code here
}
method() {
// Method code here
}
}
Thingy.prototype.foo = 'bar';
If you need to get into inheritance hierarchies, in the old ES5 syntax there's a fair bit of plumbing involved:
var Base = function() {
};
Base.prototype.method = function(arg1) {
// ...
};
var Derived = function() {
Base.call(this);
};
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
Derived.prototype.method = function(arg1) {
// Using Base's `method`, if desired, is a bit ugly:
Base.prototype.method.call(this, arg1);
};
...which is why you used to see libraries stepping in, like Prototype's Class stuff, or my own Lineage; those are outdated by ES2015 syntax, though, whcih makes it downright easy:
class Base {
method(arg1) {
// ...
}
}
class Derived extends Base {
method(arg1) {
// Use's the superclass's `method`, if desired, is easy:
super.method(arg1);
}
}
Re the title of your question:
What is the correct way to create a Javascript class?
There are several equally-correct ways to create "classes" of objects in JavaScript, because JavaScript is a very flexible language. There are standard constructor functions, "builder" functions, Object.create (on ES5-enabled environments) which lets you do more direct prototypical inheritance, and several others. One of the great things about JavaScript is that you get to choose your style of "class".
you can also use something like:
function O(x,y) {
this.x=x;
this.y=y;
this.method=function() {...}
return this;
}
var o=new O(0,0);
If you're looking for a practical solution rather than a theoretical one, you better use a framework.
Backbone.js has all you need, including mixins and an event system.
If you need some widgets too, consider
qooxdoo
ExtJS
Both of them provide a clean architecture and may be used without widgets, but they require a bit more learning than Backbone.
The inheritance structure that these frameworks provide feels very much like the common class-based one (think Java). That's because they create special objects internally that merely serve as prototypes for others, and thus take the role of classes.
For example, when you call Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }), then Ext creates a function "MyClass", and an anonymous object (MyClass.prototype) which holds the methods you provided.
If you're targeting a browser or environment that supports ES5, then you can do this:
var Person = {
foo: ...,
bar: ...
};
var Mike = Object.create(Person, { baz: ... });
This question already has answers here:
How can I emulate "classes" in JavaScript? (with or without a third-party library) [closed]
(7 answers)
Closed 10 years ago.
I have searched for a way of defining a class in javascript like in java or php but I found none!
I want something like
class javascriptClass {
function someFunction(){}
}
You can use a prototype class, like so:
function MyClass() {
}
MyClass.prototype.method1 = function() {
// do stuff
};
MyClass.prototype.method2 = function(p) {
// do stuff
};
var myClass = new MyClass();
Now, after instantiating an object myClass from the prototype MyClass, you can access the methods of the object myClass:
myClass.method1();
The above method is great if you need to instantiate more than one object/instance of the class.
If you only expect to have one object, then another method you can use simply acts as a namespace to protect your functions from collisions with others:
var myObject = {
method1: function() {
// do stuff
},
method2: function(p) {
// do stuff
}
};
myObject.method1();
In JavaScript, you don't have classes as such. You define functions that are used to create objects with new, and you can give them methods by either creating them in the body of the constructor, or adding them through the object's prototype. For example:
function JavaScriptClass() {
// I am a JavaScript constructor! Any initialization can be done here.
}
// This is the prototype! You can put instance methods and variables (to an extent) here.
JavaScriptClass.prototype.someFunction = function() {
alert('someFunction was called!');
};
// Now, let's create an instance!
var obj = new JavaScriptClass();
obj.someFunction(); // someFunction was called!
And you can access the current object using this, in both the constructor and any methods bound to the object. Note that this can also be bound to just about anything in JavaScript. It's a different type of OOP.
Unlike class-based languages, JavaScript is functional languages or prototypal language, you can't use class keyword or the kind of signature you have posted in JavaScript. In JavaScript, normally you would do:
function Person(){
// public members
this.foo = 'foo';
this.walk = function(){ ......... }
// private members
var bar = 'bar';
var baz = function(){.........}
}
var person = new Person();
I'm hesitant to use just any tutorial because I know how those tutorials can end up being, teaching you bad ways to do things. I want to setup a class in Javascript, so that I can just do
var vehicle = new Vehicle(el);
var model = vehicle->getModel();
These functions would read the HTML and get and manage the elements on the page. I'm current doing a setup like...
var model = function () {
return {
getName: function () {
},
getVehicleCount: function () {
},
incrementCount: function (id) {
console.log(x);
}
}
}();
I'm still learning classes in Javascript... I'd like to be able to pass the class a node for the element all of the methods will use, but I'm not sure I'm doing this right...
There is no such thing as a class in JavaScript, instead everything in JavaScript is an object.
To create a new object you define a function that uses the this keyword in it (a “constructor function”), and then call it with the new operator:
function Foo (id) { // By convention, constructor functions start with a capital letter
this.id = id;
}
var foo1 = new Foo(1);
var foo2 = new Foo(2);
However, these objects have no methods. To add methods, you need to define a prototype object on their constructor function:
Foo.prototype = {
getId: function () {
return this.id;
}
}
This new getId function will be usable by all Foo objects. However, as was stated, there are no classes in JavaScript and as such there are other constructs you will use in order to produce different results.
I highly recommend the videos by Douglas Crockford in which he explains much of the javascript OO nature. The talks can be found here:
http://developer.yahoo.com/yui/theater/
Douglas Crockford — The JavaScript Programming Language
Douglas Crockford — Advanced JavaScript
Those will give you a basic understanding of the structure of javascript and should help the transition from classical to functional programming.
Although there are no classes in JavaScript, you can create constructor functions. A constructor function works by binding methods to an objects prototype. There are several ways to do this, each with advantages and disadvantages. I personally prefer the most straigthforward way, which works by appending methods to "this":
var Constructor = function() {
//object properties can be declared directly
this.property = "value";
//to add a method simply use dot notation to assign an anonymous function to an object
//property
this.method = function () {
//some code
}
//you can even add private functions here. This function will only be visible to this object methods
function private() {
//some code
}
//use return this at the end to allow chaining like in var object = new Constructor().method();
return this;
}
There is nothing like classes in JavaScript. JavaScripts inheritance works with prototypes. You can take a look at base2, which mimics class-like behaviour in JavaScript.
I've been playing around with prototypal inheritance after reading http://javascript.crockford.com/prototypal.html and having a bit of a problem with understanding how I could make use of it in the way I would use classical inheritance. Namely, all functions and variables inherited by the prototype essentially become statics unless they are overwritten by the child object. Consider this snippet:
var Depot = {
stockpile : [],
loadAmmo : function (ammoType) {
this.stockpile.push(ammoType);
}
};
var MissileDepot = Object.create(Depot);
var GunDepot = Object.create(Depot);
stockpile and loadAmmo definitely should be in the prototype, since both MissileDepot and GunDepot have them. Then we run:
MissileDepot.loadAmmo("ICBM");
MissileDepot.loadAmmo("Photon Torpedo");
alert(MissileDepot.stockpile); // outputs "ICBM,Photon Torpedo"
alert(GunDepot.stockpile); // outputs "ICBM,Photon Torpedo"
This is expected because Neither MissileDepot nor GunDepot actually have stockpile or loadAmmo in their objects, so javascript looks up the inheritance chain to their common ancestor.
Of course I could set GunDepot's stockpile manually and as expected, the interpreter no longer needs to look up the chain
GunDepot.stockpile = ["Super Nailgun", "Boomstick"];
alert(GunDepot.stockpile); // outputs "Super Nailgun,Boomstick"
But this is not what I want. If this were classical inheritance (say Java), loadAmmo would operate on MissileDepot and GunDepot's stockpile independently, as an instance method and an instance variable. I would like my prototype to declare stuff that's common to children, not shared by them.
So perhaps I'm completely misunderstanding the design principles behind prototypal inheritance, but I'm at a loss as how to achieve what I've just described. Any tips? Thanks in advance!
Javascript provides a way to do this the way U are used to :)
try this:
function Depot() {
this.stockpile = [],
this.loadAmmo = function (ammoType) {
this.stockpile.push(ammoType);
}
};
var MissileDepot = new Depot();
var GunDepot = new Depot();
MissileDepot.loadAmmo("ICBM");
MissileDepot.loadAmmo("Photon Torpedo");
alert(MissileDepot.stockpile); // outputs "ICBM,Photon Torpedo"
alert(GunDepot.stockpile); // outputs ""
And U can add the functions on the fly afterwards:
MissileDepot.blow = function(){alert('kaboom');}
Extending object with another object is also an option, but what You wanted is the fact, that OO programming in javascript is done by functions not objects with {} ;)
EDIT:
I feel bad for writing that without mentioning: The javascript "new" keyword is only for making it easier to OO veterans. Please, dig deeper into the prototypal inheritance and dynamic object creation as therein lies true magic! :)
For the method, all works as expected. It's just the fields that you need to take care of.
What I see a lot in YUI, is that the constructor allocates the instance varialbes. 'Classes' that inherit from a parent call the constructor of their parent. Look here:
http://developer.yahoo.com/yui/docs/DataSource.js.html
Example base class:
util.DataSourceBase = function(oLiveData, oConfigs) {
...
this.liveData = oLiveData;
... more initialization...
}
Example subclass:
util.FunctionDataSource = function(oLiveData, oConfigs) {
this.dataType = DS.TYPE_JSFUNCTION;
oLiveData = oLiveData || function() {};
util.FunctionDataSource.superclass.constructor.call(this, oLiveData, oConfigs);
};
// FunctionDataSource extends DataSourceBase
lang.extend(util.FunctionDataSource, util.DataSourceBase, {
...prototype of the subclass...
});
To achieve what you want, you need a cloning method. You don't want an inheritance prototype, you want a cloning prototype. Take a look at one of the Object.clone() functions already implemented, like prototypejs's one: http://api.prototypejs.org/language/object.html#clone-class_method
If you want to stick to some kind of prototyping, you have to implement an initialize() method that will give a stockpile property to your newly created Depots. That is the way prototypejs Classes are defined : a cloned prototype and an initialize() method : http://prototypejs.org/learn/class-inheritance
That's because you're trying to make a cat meow! Douglas Crockford is good, but that script you're using essentially works by looping through your parent object and copying all of its attributes into the prototype chain--which is not what you want. When you put things in the prototype chain, they're shared by all instances of that object--ideal for member functions, not ideal for data members, since you want each object instance to have its own collection of data members.
John Resig wrote a small script for simulating classical inheritance. You might want to check that out.
The secret to instance variables in JavaScript is that they are shared across methods defined in superclasses or from included modules. The language itself doesn't provide such a feature, and it may not be possible to mesh with Prototypal inheritance because each instance will need it's own instance variable capsule, but by using discipline and convention it is fairly straightforward to implement.
// Class Depot
function Depot(I) {
// JavaScript instance variables
I = I || {};
// Initialize default values
Object.reverseMerge(I, {
stockpile: []
});
return {
// Public loadAmmo method
loadAmmo: function(ammoType) {
I.stockpile.push(ammoType);
},
// Public getter for stockpile
stockpile: function() {
return I.stockpile;
}
};
}
// Create a couple of Depot instances
var missileDepot = Depot();
var gunDepot = Depot();
missileDepot.loadAmmo("ICBM");
missileDepot.loadAmmo("Photon Torpedo");
alert(missileDepot.stockpile()); // outputs "ICBM,Photon Torpedo"
alert(gunDepot.stockpile()); // outputs ""
// Class NonWeaponDepot
function NonWeaponDepot(I) {
I = I || {};
// Private method
function nonWeapon(ammoType) {
// returns true or false based on ammoType
}
// Make NonWeaponDepot a subclass of Depot and inherit it's methods
// Note how we pass in `I` to have shared instance variables
return Object.extend(Depot(I), {
loadAmmo: function(ammoType) {
if(nonWeapon(ammoType)) {
// Here I.stockpile is the same reference an in the Depot superclass
I.stockpile.push(ammoType);
}
}
});
}
var nonWeaponDepot = NonWeaponDepot();
nonWeaponDepot.loadAmmo("Nuclear Bombs");
alert(nonWeaponDepot.stockpile()); // outputs ""
And that's how to do instance variables in JavaScript. Another instance variable example using the same technique.
I found the following code somewhere, but I am not understanding the code properly.
ArticleVote.submitVote('no');return false;
Is ArticleVote a class and submitVote() a function of that class?
Or what does the above code mean? And is there any concept of classes and objects in jQuery or in traditional JavaScript? How to create them? Please share some reference links or code.
Everything is an object in JavaScript
As opposed to other purportedly pure OOP languages. Functions are objects too, but they may just as well be constructor of objects.
var ObjectCreator = function () {
};
The above is a function which if called appropriately, creates an object. Called appropriately means that you have to use the new operator:
var obj = new ObjectCreator;
So while JavaScript does not have classes per se, has means to emulate that behavior. For example:
class Foo {
public void bar() {}
}
Foo foo = new Foo();
is equivalent to the following JS code:
var Foo = function () {
// constructor
};
Foo.prototype.bar = function () {}
var foo = new Foo;
Inheritance is different
The real difference comes when you want to use inheritance, which is a different type of inheritance (prototypal). So, given two pseudo-classes Foo and Bar, if we want Bar to extend from Foo, we would have to write:
var Foo = function () {};
var Bar = function () {};
Bar.prototype = new Foo; // this is the inheritance phase
var bar = new Bar;
alert(bar instanceof Foo);
Object literals
While constructor functions are useful, there are times when we only need only one instance of that object. Writing a constructor function and then populate its prototype with properties and methods is somehow tedious. So JavaScript has object literals, which are some kind of hash tables, only that they're self-conscious. By self-conscious I mean that they know about the this keyword. Object literals are a great way to implement the Singleton pattern.
var john = {
age : 24,
isAdult : function () {
return this.age > 17;
}
};
The above, using a constructor function would be equivalent to the following:
var Person = function (age) {
this.age = age;
};
Person.prototype.isAdult = function () {
return this.age > 17;
};
var john = new Person(24);
What about that prototype thingy
As many have said, in JavaScript objects inherit from objects. This thing has useful aspects, one of which may be called, parasitic inheritance (if I remember correctly the context in which Douglas Crockford mentioned this). Anyway, this prototype concept is associated with the concept of prototype chain which is similar to the parent -> child chain in classical OO languages. So, the inheritance stuff. If a bar method is called on a foo object, but that object does not have a bar method, a member lookup phase is started:
var Baz = function () {};
Baz.prototype.bar = function () {
alert(1);
};
var Foo = function () {};
Foo.prototype = new Baz;
var foo = new Foo;
/*
* Does foo.bar exist?
* - yes. Then execute it
* - no
* Does the prototype object of the constructor function have a bar
* property?
* - yes. Then execute it
* - no
* Is there a constructor function for the prototype object of
* the initial construct function? (in our case this is Baz)
* - yes. Then it must have a prototype. Lookup a bar
* member in that prototype object.
* - no. OK, we're giving up. Throw an error.
*/
foo.bar();
Hold on, you said something about parasitic inheritance
There is a key difference between classical OO inheritance and prototype-based inheritance. When objects inherit from objects, they also inherit state. Take this example:
var Person = function (smart) {
this.smart = smart;
};
var Adult = function (age) {
this.age = age;
};
Adult.prototype = new Person(true);
var john = new Adult(24);
alert(john.smart);
We could say that john is a parasite of an anonymous Person, because it merciless sucks the person intelligence. Also, given the above definition, all future adults will be smart, which unfortunately is not always true. But that doesn't mean object inheritance is a bad thing. Is just a tool, like anything else. We must use it as we see fit.
In classical OO inheritance we can't do the above. We could emulate it using static fields though. But that would make all instances of that class having the same value for that field.
Javascript supports objects but not classes - it uses a prototype-based object system.
JavaScript supports object-oriented development
Object-oriented JavaScript
Certainly JS has objects and classes, but it's not exactly a conventional approach.
It's rather a broad question, but there's three main things you want to know about objects and classes in JS:
1). Everything is an object - this famously includes JS's first class functions
2). There are object literals
var myObject = { "foo": 123, "bar": [4,5,6] };
3). Inheritance is prototype based, so creating classes is more a matter of form than function. To get the effect of a class you'd write something like:
function myClass(foo)
{
this.foo = foo;
}
myClass.prototype.myFooMethod = function() {alert(this.foo);}
var myInstance = new myClass(123);
myinstance.myFooMethod(); // alerts 123
For your example it's likely that ArticleVote is an object instance and probably not conceptually a class, and submitVote would be a method of the object. can't tell for sure though, it could be what you'd call a static method in another language.
Yes, JavaScript has impressive support for Object Oriented programming, Objects and functions. In fact, I'm surprised that you have to ask this question! There are a wealth of resources online such as:
http://mckoss.com/jscript/object.htm
http://www.webreference.com/js/column79/
http://www.javascriptkit.com/javatutors/oopjs.shtml
More resources:
http://www.google.com/search?q=object+oriented+programming+javascript
JavaScript frameworks such as jQuery and Prototype could not have been built without this support in JavaScript engines.
You can achieve the above through Javascript, nothing to do with jQuery.
var ArticleVote= {};
ArticleVote.submitVote = function(voteResult) {
console.log(voteResult);
}
function Vote(){
ArticleVote.submitVote('no');
return false;
}
You can use the JavaScript function as class.
ClassUtil = function(param){
privateFunction = function(param){
// Do some thing
return valueParam;
}
this.publicFunction = function(){
var val1 = function1();
if (val1){
return true;
} else{
return false;
}
}
}
function getClass(){
var classUtil = new ClassUtil();
alert(classUtil.publicFunction());
}
There is one public and one private function. You can call public function from out side using object of the class.