I have this function here, I need to work with this other function called OrderRepository in another file.
main.js
function main() {
var orderRepo = new OrderRepository();
// Your code here
}
orderrepository.js
function OrderRepository() {
}
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
These were given as examples to use, 1 question rolled into 2 parts:
1) var orderRepo = new OrderRepository();
Can you initialize a function like this?
2) In the orderrepository.js:
function OrderRepository() {
}
is being called in main.js, but nothings inside of it, this was given as-is in the assignment, is this just a typo and really they meant to throw everything inside that function or am I missing something?
Shouldn't it look like this?
Expected
function OrderRepository() {
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [{ array of objects }],
return yesterdaysOrders;
};
}
Diving deeper into JavaScript, the language is hard to understand. JavaScript is not really OOP (imho), at least it does not implement the common OOP concept. Some call it object-based language. There are no classes. Recent ECMA Script standards do implement the class keyword, however, it is syntax sugar. Used with the new keyword it builds the same objects as you can achieve by 'constructor' functions.
Everything in JavaScript is an object, even numbers and functions. Every function can act as constructor function. The new keyword call a constructor function with a newly creates empty object as the function's this context. The function can do what it wants. If it does not return anything, its this context is returned by the new expression.
Since there are no classes, there is no inheritance. Some inheritance-like behavior is achieved by the prototype concept. In most cases the constructor will return nothing and sometimes modify the this object by adding properties. Methods are properties holding a function object. The object in the new context of a constructor call will have a prototype object reference as the __proto__ property. This is copied by the new operator from the prototype property of the called constructor function. The default is an empty object.
// empty constructor function
function OrderRepository() {
}
// define a function property on the constructor's prototype object
OrderRepository.prototype.getYesterdaysOrders = function
getYesterdaysOrders() {
var yesterdaysOrders = [ /* array of objects */ ],
return yesterdaysOrders;
};
// create an empty object with a `__proto__` property holding a
// reference to the object { getYesterdaysOrders: function(){/*code*/} }
var obj = new OrderRepository();
Now, when the method invocation obj.getYesterdaysOrders() is tried, JavaScript will look if there is such a property defined in obj. If not, it looks if there is a reference in obj.__proto__ and the property name is searched the properties of obj.__proto__. If not, the same step is repeated until it was found or the __proto__ property in the chain is null. Since obj.__proto__.getYesterdaysOrders is defined, it is checked if it is a callable function object and finally invoked with a this context of obj since we called obj.getYesterdaysOrders(). Otherwise an error is thrown.
NOTE: Even if the major browsers do expose the __proto__ property, it is not part of the standards. Do not use it directly (except for debugging at development time) and even more important: do not manipulate it. If you really need to get or manipulate a prototype (__proto__) of an object instance after construction, use the methods of the builtin Object object.
Upon your last edit: Your expected code would define a new function object in prototype on each instantiation (and thus constructor invocation). This is not what you want, it's just needless overhead.
Regarding the first part, it looks like this assignment is dealing with how to create instances of objects in JavaScript as that is what the new operator does.
You can find more information regarding new on the MDN.
Regarding the second question, it is dealing with how to create objects that inherit methods. So, yes it is empty, until you get to the prototype expression.
The expected code would not give you the inheritance in this case. Notice how OrderRepository is repeated inside the function, which would be invalid. Javascript requires you to add inheritance to the special prototype property. Code that is added to the function declaration, would be scoped to the function only in that case.
You can find more information about prototype on the MDN.
Related
I have been going through Javascript Koans when I hit upon the part about inheritance. I became deeply fascinated and spent the entire morning researching how inheritance works in JS.
I understand that a function can be used to execute code which is declared in its code body, and a function can also serve the purpose as a constructor for objects which inherent from that functions prototype object.
It seems as though functions have two purposes that are not at all related- the ability to create objects, and the ability to execute it's declared code. Is there any relationship between these two abilities?
An attempt at a simple answer (with some approximations to try and keep it simple)
You could see a "class" function both as the constructor of the underlying object and the place where its methods are defined.
Construction
The new operator will create an empty object whose type will reference the function and bind it to this, then call the function.
The function may set some properties of this, which will become values for the new instance properties.
Methods
In JavaScript almost everything, notably functions, can have properties.
Among these, the conventionally named prototype property is the container of all class methods (and possibly other property values).
function Guy (name) { this.name = name; }
Guy.prototype = {
sayHello: function () { console.log ("Hello, I'm "+this.name; }
}
the Guy method sayHello is literally the property Guy.prototype.sayHello, which happens to be a function.
You could just as well add values instead of functions to the prototype property, which would act as class variables (of sorts).
So let's create an object Bob from the function/class Guy:
var Bob = new Guy("Bob");
Bob.sayHello();
when you invoke Bob.sayHello(), the virtual machine will first look for a Bob.sayHello property (which usually does not exist), then for a Guy.prototype.sayHello (and would go up the inheritance chain or die trying, but that's another subject), then bind this to Bob and call Guy.prototype.sayHello, which will be able to access the Bob instance through this.
As an illustration of the mechanism, you can break the prototype chain for a given object instance:
Bob.sayHello = function () { console.log ("my real name is Robert"); }
The duality you're describing doesn't in fact exist. Functions exist to be executed. But, in JavaScript, functions are also objects, so they can have properties such as prototype. (You can add other properties to your function and use them from its body as a means of making it "stateful".) From the function's point of view, prototype is just another ordinary property.
Object construction is the domain of the new operator. What it does, is this:
it creates an empty object,
it creates a hidden, non-modifiable binding between the created object and its constructor, which is then used to look-up a property value on its prototype whenever a property doesn't exist on the object itself,
it executes the provided function in context of that object (this points to it during that function's execution), and
it returns either the created object (if the provided function returned undefined) or the return value of the provided function.
(The {} notation for creating objects is just a shortcut for new Object().)
Additional note on prototypal inheritance (that is used in JavaScript): The second step in the above sequence has an important result. Any object in JavaScript has a constructor ({} has Object as constructor), so setting an object as the value of prototype property of your function doesn't just create a single binding. It transitively creates a "prototype chain". Any property is then looked up first on the object, then on its constructor's prototype, then on it's constructor's prototype's constructor's prototype, etc.
var Ninja = function() {
this.swingSword = function() {
return true
}
}
Ninja.swingFire = function() {
return true
}
var ninja = new Ninja()
assert(ninja.swingFire()) // undefined
So it's creating a new object of Ninja, but why isn't swingFire included in this situation? Could someone explain why?
Instances created with new will inherit from constructor.prototype, not from the constructor object itself. This will behave as you want:
Ninja.prototype.swingFire = function() {
return true;
}
If you want to know how objects, functions, "classes" and inheritance in Javascript work, you should take a look at this video:
The Definitive Guide to Object-Oriented JavaScript: http://youtu.be/PMfcsYzj-9M
This is the best explanation of object orientation in JS that I have ever seen.
In your case, the following happens:
When you create a new Ninja(), you create a new empty object ({}) with a prototype property that points to the functions's prototype. Then the function Ninja will be called as the constructor for your newly created object. It creates the swingSword function and makes it a method of your object.
The swingFire function will not be assigned to your created object, because it is a method of the function itself, not its prototype. Functions are objects as well, so they can actually have properties.
If an object does not have a certain property or method, it looks at it's prototype. If the prototype has the said property/method, it uses it instead. That means that if you give the prototype a method, every object that uses it can use this method as well. That's why you assign methods to the prototype of a function.
Again: Watch the video and you will understand this explanation.
Recently I read a tutorial which says if define the function like below.
function Animal() { }
On the surface, this code seems to create a function called Animal.
But with JavaScript, the full truth is slightly more complicated. What
actually happens when this code executes is that two objects are
created. The first object, called Animal, is the constructor function
itself. The second object, called Animal.prototype, has a property
called Animal.prototype.constructor, which points to Animal. Animal
has a property which points back to its prototype, Animal.prototype.
But I have little confuse about it .What about the Function object ?What is the use for the Animal object?
And If I write code like below .
var test= new Function();
and I inspected the variable test in the Developer tool of the Chrome.
I found test is nothing to do with the Function. Can someone tell me why ? thanks.
Updated
The diagram below is the objects relationship when the code is executed, please review it.
If my understanding is wrong. please correct me. thanks.
That blog post goes into a lot of detail that's interesting but unnecessarily confusing for most people most of the time.
First, let's talk about functions; forget about prototypes for a minute. When you create a function:
function Whatever() {
// ...
}
you've created an object. That is, all functions are objects, and they're constructed via the Function built-in constructor. The symbol "Whatever" in this example will have as its value a reference to that object.
Given a reference to a function, it's possible to call it:
Whatever(); // call the function
It's possible to take that value (the reference to the function object) and assign it to another variable, or pass it as a parameter to another function, or to use it just like any other value in JavaScript.
var another = Whatever;
another(); // also calls the "Whatever" function
Constructing a function via the Function constructor explicitly is something that's rarely done, but it gives you a function that's otherwise unremarkable. (In the OP, the constructed function doesn't do anything because no code was passed to the Function constructor.)
Now, things get interesting when a function is invoked as part of a new expression.
var test = new Whatever();
By using new, a new object is instantiated and associated with the "Whatever" function. The "Whatever" function is the constructor for that new object.
Every function object, whether it's ever used as a constructor or not, has an associated "prototype" object. When a function is used as a constructor, then objects it constructs (that is, objects made in new expressions that invoke the function) are implicitly associated with that prototype object.
The prototype object becomes interesting when an object property reference expression is evaluated. Object property references look like this:
obj.name
obj[ nameExpression ]
In such an expression, the property name (either the identifier used in the . expression or the value of the expression inside [ ]) is checked against the set of properties on the object directly. If the name is not the same as one of the object's properties, then the runtime consults the prototype object associated with the constructor function used to make the object.
For most code that most people write, that relationship and some of its direct implications are the only things to worry about. You don't have to fool around with the (non-standard, at this time) "proto" property of objects unless you're putting together some sort of library or framework.
Finally, it might be instructive to look at the Object.create() function and in particular the "polyfill" shown in that documentation.
Please help me to understand below code. This is the script for drag and drop object. I am trying to explore it but struck at one thing.
URL for Reference (Complete Script)
I dont understand how this method creation work, like get x(), set x() etc. Is get and Set is predefined object? will it actually set object value or get specific value of object, like we have in date object.
Also there is one space between its declaration set x(), why?
I am new to java script, i really appreciate your help.
// position strings are "x,y" with no units
get x()
{
return parseInt(this._position.split(',')[0]);
},
set x(inX)
{
var comps = this._position.split(',');
comps[0] = inX;
this.position = comps.join(',');
},
get y()
{
return parseInt(this._position.split(',')[1]);
},
set y(inY)
{
var comps = this._position.split(',');
comps[1] = inY;
this.position = comps.join(',');
},
Let's start by calling the language 'JavaScript' not 'java script'; the language is standardized as Ecmascript.
Look up creation of methods in Ecmascript (JavaScript). The functions set(inX) and get() are methods be of some prototype - the clue is the this reference referencing the current instance. However, one should write function get(), and function set(inX) instead.
From Wikipedia:
Prototype-based
prototypes
JavaScript uses prototypes instead of classes for inheritance. It
is possible to simulate many class-based features with prototypes in
JavaScript. functions as object constructors
Functions double as object constructors along with their typical
role. Prefixing a function call with new creates a new object and
calls that function with its local this keyword bound to that object
for that invocation. The constructor's prototype property determines
the object used for the new object's internal prototype. JavaScript's
built-in constructors, such as Array, also have prototypes that can be
modified. functions as methods
Unlike many object-oriented languages, there is no distinction
between a function definition and a method definition. Rather, the
distinction occurs during function calling; a function can be called
as a method. When a function is called as a method of an object, the
function's local this keyword is bound to that object for that
invocation.
I am just learning Javascript and I was wondering, is using the prototype declaration, like this:
function TSomeObj()
{
this.name="my object";
}
TSomeObj.prototype.showname = function() {
alert(this.name);
}
Basically the same as doing it like this:
function TSomeObj()
{
this.name="my object";
this.showname = function() {
alert(this.name);
}
}
When I dump the object's properties I get the same result:
TSomeObj (inline version) =
{
'name': 'my object',
'test': function
}
TSomeObj (prototype declaration) =
{
'name': 'my object',
'test': function
}
What exactly is the benefit of using prototype declarations? Except less cluttering and more orderly sourcecode perhaps.
Update: I should perhaps have made it more clear that it was the final result i was curious about. The end result is ofcourse the same (i.e both register a new function in the object prototype) - but the way they do it is wildly different. Thank you for all replies and info!
Note: This answer is accurate but does not fully reflect the new way to create classes in JavaScript using the ES6 class Thing {} syntax. Everything here does in fact apply to ES6 classes, but might take some translation.
I initially answered the wrong question. Here is the answer to your actually-asked question. I'll leave my other notes in just in case they're helpful to someone.
Adding properties to an object in the constructor function through this.prop is different from doing so outside through Object.prototype.prop.
The most important difference is that when you add a property to the prototype of a function and instantiate a new object from it, that property is accessed in the new object by stepping up the inheritance chain rather than it being directly on the object.
var baseobj = {};
function ObjType1() {
this.prop = 2;
}
function ObjType2() {}
ObjType1.prototype = baseobj;
ObjType2.prototype = baseobj; // these now have the *same* prototype object.
ObjType1.prototype.prop = 1;
// identical to `baseobj.prop = 1` -- we're modifying the prototype
var a = new ObjType1(),
b = new ObjType2();
//a.hasOwnProperty('prop') : true
//b.hasOwnProperty('prop') : false -- it has no local property "prop"
//a: { prop = 2 }, b : { prop = 1 } -- b's "prop" comes from the inheritance chain
baseobj.prop = 3;
//b's value changed because we changed the prototype
//a: { prop = 2 }, b : { prop = 3 }
delete a.prop;
//a is now reflecting the prototype's "prop" instead of its own:
//a: { prop = 3 }, b : { prop = 3 }
A second difference is that adding properties to a prototype occurs once when that code executes, but adding properties to the object inside the constructor occurs each time a new object is created. This means using the prototype performs better and uses less memory, because no new storage is required until you set that same property on the leaf/proximate object.
Another difference is that internally-added functions have access to private variables and functions (those declared in the constructor with var, const, or let), and prototype-based or externally-added functions do not, simply because they have the wrong scope:
function Obj(initialx, initialy) {
var x = initialx,
y = initialy;
this.getX = function() {
return x;
}
var twoX = function() { // mostly identical to `function twoX() { ... }`
return x * 2;
}
this.getTwoX = function() {
return twoX();
}
}
Obj.prototype.getY = function() {
return y; // fails, even if you try `this.y`
}
Obj.prototype.twoY = function() {
return y * 2; // fails
}
Obj.prototype.getTwoY = function() {
return twoY(); // fails
}
var obj = new Obj();
// obj.y : fails, you can't access "y", it is internal
// obj.twoX() : fails, you can't access "twoX", it is internal
// obj.getTwoX() : works, it is "public" but has access to the twoX function
General notes about JavaScript objects, functions, and inheritance
All non-string and non-scalar variables in JavaScript are objects. (And some primitive types undergo boxing when a method is used on them such as true.toString() or 1.2.valueOf()). They all act somewhat like a hash/dictionary in that they have an unlimited(?) number of key/value pairs that can be assigned to them. The current list of primitives in JavaScript is: string, number, bigint, boolean, undefined, symbol, null.
Each object has an inheritance chain of "prototypes" that go all the way up to the base object. When you access a property of an object, if that property doesn't exist on the object itself, then the secret prototype of that object is checked, and if not present then that object's prototype, so on and so forth all the way up. Some browsers expose this prototype through the property __proto__. The more modern way to get the prototype of an object is Object.getPrototypeOf(obj). Regular objects don't have a prototype property because this property is for functions, to store the object that will be the prototype of any new objects created using that function as their constructor.
A JavaScript function is a special case of an object, that in addition to having the key/value pairs of an object also has parameters and a series of statements that are executed in order.
Every time a function object is invoked it is paired with another object that is accessed from within the function by the keyword this. Usually, the this object is the one that the function is a property of. For example, ''.replace() boxes the string literal to a String, then inside the replace function, this refers to that object. another example is when a function is attached to a DOM element (perhaps an onclick function on a button), then this refers to the DOM element. You can manually choose the paired this object dynamically using apply or call.
When a JavaScript function is invoked with the new keyword as in var obj = new Obj(), this causes a special thing to happen. If you don't specifically return anything, then instead of obj now containing the return value of the Obj function, it contains the this object that was paired with the function at invocation time, which will be a new empty object with the first parent in its inheritance chain set to Obj.prototype. The invoked Obj() function, while running, can modify the properties of the new object. Then that object is returned.
You don't have to worry much about the keyword constructor, just suffice it to say that obj.constructor points to the Obj function (so you can find the thing that created it), but you'll probably not need to use this for most things.
Back to your question. To understand the difference between modifying the properties of an object from within the constructor and modifying its prototype, try this:
var baseobj = {prop1: 'x'};
function TSomeObj() {
this.prop2 = 'y';
};
TSomeObj.prototype = baseobj;
var a = new TSomeObj();
//now dump the properties of `a`
a.prop1 = 'z';
baseobj.prop1 = 'w';
baseobj.prop2 = 'q';
//dump properties of `a` again
delete a.prop1;
//dump properties of `a` again
You'll see that setting a.prop1 is actually creating a new property of the proximate object, but it doesn't overwrite the base object's prop1. When you remove prop1 from a then you get the inherited prop1 that we changed. Also, even though we added prop2 after a was created, a still has that property. This is because javascript uses prototype inheritance rather than classic inheritance. When you modify the prototype of TSomeObj you also modify all its previously-instantiated objects because they are actively inheriting from it.
When you instantiate a class in any programing language, the new object takes on the properties of its "constructor" class (which we usually think of as synonymous with the object). And in most programming languages, you can't change the properties or methods of the class or the instantiated object, except by stopping your program and changing the class declaration.
Javascript, though, lets you modify the properties of objects and "classes" at run-time, and all instantiated objects of that type class are also modified unless they have their own properties that override the modification. Objects can beget objects which can beget objects, so this works in a chain all the way up to the base Object class. I put "classes" in quotes because there really isn't such a thing as a class in JavaScript (even in ES6, it's mostly syntactic sugar), except that the new keyword lets you make new objects with the inheritance chain hooked up for you, so we call them classes even though they're just the result of constructor functions being called with the new keyword.
Some other notes: functions have a Function constructor, objects have an Object constructor. The prototype of the Function constructor is (surprise, surprise) Object.
Inheriting from an object without the constructor function running
In some cases, it's useful to be able to create a new "instance of an object" without the constructor function running. You can inherit from a class without running the class's constructor function like so (almost like manually doing child.__proto__ = parent):
function inheritFrom(Class) {
function F() {};
F.prototype = Class.prototype;
return new F();
}
A better way to do this now is Object.setPrototypeOf().
The accepted answer missed the most important distinctions between prototypes and methods bound to a specific object, so I'm going to clarify
Prototype'd functions are only ever declared once. Functions attached using
this.method = function(){}
are redeclared again and again whenever you create an instance of the class. Prototypes are, thus, generally the preferred way to attach functions to a class since they use less memory since every instance of that class uses the same functions. As Erik pointed out, however, functions attached using prototypes vs attached to a specific object have a different scope, so prototypes don't have access to "private" variables defined in a function constructor.
As for what a prototype actually is, since it's an odd concept coming from traditional OO languages:
Whenever you create a new instance of a function:
var obj = new Foo();
the following logic is run (not literally this code, but something similar):
var inheritsFrom = Foo,
objectInstance = {};
objectInstance.__proto__ = inheritsFrom.prototype;
inheritsFrom.apply( objectInstance, arguments );
return objectInstance;
so:
A new object is created, {}, to represent the new instance of the function
The prototype of the function is copied to __proto__ of the new object. Note that this is a copy-by-reference, so Foo.prototype and objectInstance.__proto__ now refer to the same object and changes made in one can be seen in the other immediately.
The function is called with this new object being set as this in the function
and whenever you try to access a function or property, e.g.: obj.bar(), the following logic gets run:
if( obj.hasOwnProperty('bar') ) {
// use obj.bar
} else if( obj.__proto__ ){
var proto = obj.__proto__;
while(proto){
if( proto.hasOwnProperty('bar') ){
// use proto.bar;
}
proto = proto.__proto__;
}
}
in other words, the following are checked:
obj.bar
obj.__proto__.bar
obj.__proto__.__proto__.bar
obj.__proto__.__proto__.__proto__.bar
... etc
until __proto__ eventually equals null because you've reached the end of the prototype chain.
Many browsers actually expose __proto__ now, so you can inspect it in Firebug or the Console in Chrome/Safari. IE doesn't expose it (and may very well have a different name for the same thing internally).