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.
Related
I have been playing around with the concept of "factory functions" so consider:
var HelloWorld = function() {
return {
hello: function() { console.log('hi'); }
}
}
Which as we know is instantiated as: var helloWorld = HelloWorld(); Would the "constructor" of such a function be the function it's self? And is there any way I could just do: HelloWorld.hello() instead of "instantiating it" like a class? Or is that a whole other concept?
Take a look at following code:
var HelloWorldFactory = function(text) {
return {
hello: function() { console.log(text); }
}
};
var HelloWorld = {
hello: function() { console.log('hi2'); }
};
var helloWorld = HelloWorldFactory('hi');
helloWorld.hello();
HelloWorld.hello();
as #Quentin mentioned in comment by calling HelloWorldFactory('hi'); you are not calling js constructor but just a function which returns an object.
Doing HelloWorld.hello(); is a different concept because you just use aleardy defined object(it can be created via factory or just defined in code)
In your example you are returning an object literal with a function property. You could have returned directly a function as well. But at the end this is the factory pattern and created functions' constructor is the Function function not the HelloWorld function's prototype as it would be the case with constructors.
Functions are pure objects in JS. You can treat them just like objects. So do whatever you like to do with them.
function HelloWorld(){};
HelloWorld.thank = function(){console.log("thanks")};
HelloWorld.message = "hello";
HelloWorld.sayMessage = function(){console.log(HelloWorld.message)};
However constructor functions are slightly different. They are invoked with the new keyword and as i have mentioned above they assign their own prototype to the created object. It's one of the most complicated parts of JS. I have seen many people thinking new is useless, better be avoided and Object.create() should be preferred instead but it's not the case. There are times constructor functions are very useful since you can establish amazing prototypical relationships during the construction time.
I have been looking deeply into JavaScript lately to fully understand the language and have a few nagging questions that I can not seem to find answers to (Specifically dealing with Object Oriented programming).
Assuming the following code:
function TestObject()
{
this.fA = function()
{
// do stuff
}
this.fB = testB;
function testB()
{
// do stuff
}
}
TestObject.prototype = {
fC : function
{
// do stuff
}
}
What is the difference between functions fA and fB? Do they behave exactly the same in scope and potential ability? Is it just convention or is one way technically better or proper?
If there is only ever going to be one instance of an object at any given time, would adding a function to the prototype such as fC even be worthwhile? Is there any benefit to doing so? Is the prototype only really useful when dealing with many instances of an object or inheritance?
And what is technically the "proper" way to add methods to the prototype the way I have above or calling TestObject.prototype.functionName = function(){} every time?
I am looking to keep my JavaScript code as clean and readable as possible but am also very interested in what the proper conventions for Objects are in the language. I come from a Java and PHP background and am trying to not make any assumptions about how JavaScript works since I know it is very different being prototype based.
What is the difference between functions fA and fB
In practice, nothing. The primary difference between a function expression (fA) and a function declaration (fB) is when the function is created (declared functions are available before any code is executed, whereas a function expression isn't available until the expression is actually executed). There are also various quirks associated with function expressions that you may stumble across.
In the example, I'd use a function expression, simply because declaring a function expression, then assigning the result seems a bit abstracted. But there is nothing "right" or "wrong" about either approach.
If there is only ever going to be one instance of an object at any given time, would adding a function to the prototype such as fC even be worthwhile?
No. Just about everyone who goes does inheritance finds that plain objects are often simpler and therefore "better". Prototype inheritance is very handy for patching built–in objects though (e.g. adding Array.prototype.each where absent).
And what is technically the "proper" way to add methods to the prototype…
There isn't one. Replacing the default prototype with some other object seems like a bit of a waste, but assigning an object created by a literal is perhaps tidier and easier to read that sequential assignments. For one or two assignments, I'd use:
Constructor.prototype.method = function(){…}
but for lots of methods I'd use an object literal. Some even use a classic extend function and do:
myLib.extend(Constructor.prototype, {
method: function(){…}
});
Which is good for adding methods if some have already been defined.
Have a look at some libraries and decide what you like, some mix and match. Do whatever suits a particular circumstance, often it's simply a matter of getting enough code to all look the same, then it will look neat whatever pattern you've chosen.
fA and fB are effectively the same and it is just a matter of convention.
If there is only one instance of a object I wouldn't even use a constructor function, but rather just a object literal, such as:
var o = {
fA: function () { ... },
fB: function () { ... },
fC: function () { ... }
};
As for adding it to an instance or a prototype, the instance is slightly more efficient than adding it to the prototype if you only have one instance but, as I said, use a literal instead.
I avoid declaring functions in the constructor because each invocation of the constructor will create new object representing each function. These objects are not very large they tend to add up if many objects are created. If the functions can be moved to the prototype, it is much more efficient to do so.
As for adding to the prototype, I favor the
TestObject.prototype.functionName = function () { };
style but it is a matter of preference. I like the above because it looks the same whether you are extending the prototype or creating the intial prototype.
Also are there any definitive JavaScript style guides or documentation
about how JavaScript operates at a low level?
Damn no javascript programmer should ever miss "Professional JavaScript for Web Developers". This is a fantastic book, that goes into the deep. It explains objects, class emulation, functions, scopes and much much more. It is also a JS reference.
And what is technically the "proper" way to add methods to the
prototype the way I have above or calling
TestObject.prototype.functionName = function(){} every time?
As for the way to define classes, I would recommend to have a look at various JS MVC frameworks (like Spine.js, which is lightweight ). You do not need the whole of them, just their class emulation libraries. The main reason for this, is that JS does not have the concept of classes, rather it is purely consisted of objects and prototypes. On the other hand classes can be perfectly emulated (please do not take the word emulated as it is something missing). As this needs some discipline from the programmer, it is better to have a class emulation library to do the job and make you code cleaner.
The standard methods that a programmer should expect of a class emulation library are:
// define a new Class
var AClass = Class.create({
// Object members (aka prototype),
// usually an initialize() method is called if it is defined
// as the "constructor" function when a class object is created
}, {
// Static members
});
// create a child class that inherits methods and attributes from parent
var ChildClass = AClass.extend({
// Child object members
},{
// Child static members
});
AClass.include({
// Object amendments (aka mixin), methods and attributes
// to be injected to the class object
},{
// Statics amendments, methods and attributes to be
// injected as class static members
});
// check object type
var aObj = new AClass();
aObj instanceof AClass; // true
aObj instanceof ChildClass; // false
var cObj = new ChildClass();
cObj instanceof AClass; // true
cObj instanceof ChildClass; // true
I answer for first part: there is no differences, when you declare function not as variable then declaration of it rises in the block, so
...
func();
...
function func () { ... }
is equal to
var func = function () { ... };
...
func();
...
So your code
function TestObject () {
this.fA = function() { // do stuff };
this.fB = testB;
function testB() { // do stuff }
}
is equal to
function TestObject () {
var testB = function () { // do stuff };
this.fA = function () { // do stuff };
this.fB = testB;
}
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: ... });
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.
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.