I've been reading the book named "Object Oriented Javascript" by Stoyan Stefanov. I see this sentence:
function is actually an object that is built with 'Function' constructor function (with capital F).
The author demonstrates this with some nice examples. However, based on that statement, I got this question that can't be answer by myself. As 'Function' constructor is a function, so 'Function' function is an Object, then 'Function' object needs another constructor function to build it and that another constructor function is again an Object (because it's a function).
Well, I end up with this endless logic. Can someone help me point out the wrong point in my thinking?
'Function' function is an Object, then 'Function' object needs another constructor function to build it
No. Function is a native, builtin object whose properties and behavior are defined in section 15.3 of the EcmaScript specification. It was not built by an js function.
Think of it like that: There is a function somewhere in the code of your EcmaScript environment that builds function objects - it is called whenever your script encounters a function expression or declaration. The global Function function is a wrapper for that function to make it accessible for scripts. All function objects which that function returns inherit from the Function.prototype object - it looks like they were constructed by Function. Also the Function.prototype.constructor property that all functions inherit is defined to point to Function.
A function in JS embeds 2 concepts:
An entity
A functionality
A function entity is some sort of "capsule" that contains a functionality, i.e., the power of transforming several inputs into an output. This capsule is what we know as "object". At the end of this recursion you find the identity Function.constructor === Function, which sets the limits of the introspective features of the language. The rest of JS functionalities cannot be accessible by the language itself because there not exists any capsule or object that embeds them.
In JS you cannot define standalone 'functionalities' but you create objects that implement such functionalities that can be treated as any other objects. The Function object is the core object for implementing functionalitites. Either if you define named or anonymous functions (by means of the function keyword) you are creating a Function object that is bound either to a name (for named functions) or directly to a variable (unnamed functions).
function foo(a, b) { return a+b; } //This function is a Function object bound to the name `foo`
var a = function(a, b) { return a+b; } //the Function object is bound to `a`
In the same manner the Array object has the [] operator, which is used to access to array elements, you may interpret () as an operator of the Function object which is used for invoking its embedded functionality.
Related
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.
How are functions stored in a variable?
According to MDN
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
Suppose this scenario,
var fn = function () {};
fn.attr = 3;
console.log(fn); //prints function() {}
console.log(Object.keys(fn)); //prints ["attr"]
If a function is an object shouldn't it have keys and value kind where the function is stored in a property and the interpreters don't show that property? Something like C++ style operator overloading or array/object representation in Javascript itself. I mean to say are functions (or arrays) are just objects treated in a different manner? Which might imply that anonymous functions are stored in an object with a hidden property.
In summary, what is the underlying working of functions(or arrays)? Are they treated specially? Or are they just syntactic sugar for some hidden property which is called when () is used?
Yes, functions are special.
Proof
const f = Object.create(Function.prototype);
f(); // TypeError: f is not a function
Exposition
They are "callable objects" that can only be created via prescribed syntax (function expressions, statements, declarations, fat-arrows, object literal method definition shorthand, Function constructor, class methods).
That means they have a special [[Call]] method (not visible to you) that is called when you invoke them with the () syntax.
[[Call]] coordinates:
the creation of the execution context (call-stack frame)
addition of the new execution context to the top of the stack
execution of the function logic
removal of the execution context from the stack
cueing up the next context to run (the one immediately lower on the stack)
supplying any return value to the next execution context
Creation of the execution context in turn completes configuration of the LexicalEnvironment (used for scoping), configuration of the receiver (this) for the function and other meta-logic.
Functions also differ from most normal objects in that they have Function.prototype on their [[Prototype]] chain (although you can create your own 'useless' object by inheriting from Function.prototype - see above).
For a full list of differences, please see MDN, the spec etc.
Can anyone explain this ?
I read that functions are just an object in Javascript just that is callable . I.e a function is a subset of object (hashmaps) .
However an object is created using function like this
function Constructor() {}; a = new Constructor();
a = {} ; //a.constructor is the 'Object' Function
//And Douglas Crockfords Object.create(a) does this
Object.create = function(obj){
function F();
F.prototype = obj;
return new F();
}
So the question is that if an object itself is created from a function , how can it be the superset ? I am sure my logical reason is failing somewhere but not quite clear as to what is it that I fail to understand ! Feels like a bit of Chicken and Egg problem . Can anyone help with my logical fallacy ?
PS: This question's essence has something to do with this What is a metaclass in Python?
Constructor functions do not create objects. The exact action "create an object" doesn't exist as a construct in javascript - although there are constructs that involve creating an object(and doing other things alongside it) - object literals {}, the new operator, etc.
See for example the new operator. When you use it with a function, it calls the function's internal [[Construct]] property : http://es5.github.io/#x13.2.2 :
1. Let obj be a newly created native ECMAScript object. - you could say it's created by the system or some other way to describe an external source.
After the object is created, it is passed to the constructor function as the this parameter:
8. Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
Then the constructor function can decorate it, add, modify properties, and so on. But it's not the function itself creating the object.
What's an object? It's a software component that encapsulates state and behavior together into a single entity in memory.
By that definition, you can see where everything can be thought of as an object. Functional programmers make functions first class objects. Data folks would say that data, even that without behavior, can be thought of as an object (albeit not a very smart one).
JavaScript treats functions as objects.
You are confusing the Object that is exclusive to JavaScript with the "object" of OOP.
Answering my own question :
I read that functions are just an object in Javascript just that is callable . I.e a function is a subset of object (hashmaps) .
functions (javascript functions) are subset of hashmaps or objects (but not that is not javascript objects) it is the general concept of objects as mentioned by jonLuci .
What's an object? It's a software component that encapsulates state and behavior together into a single entity in memory. functions in javascript is a part of this software conception of objects/hashmaps .
So the question is that if an object itself is created from a function , how can it be the superset ?
The logical fallacy in this is that, object in this context should read as "javascript object" and not the object in the generic sense of the word . javascript objects are created from functions as explained by the chosen answer!
In other words
hashmaps(objects in generic sense) > functions > javascript objects
> is used to mean kind of a superset relation .
javascript objects having callability i.e () can be considered to be javascript functions .
javascript functions are just hashmaps or objects in the very generic sense of the term !
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.