If you haven't yet been rolling on the floor laughing today, you could try this. Read the article, and then the comment below ...
If this didn't make you ROFL, go further and try to find out what's the meaning of Array.prototype.slice.call(arguments, 1)
. For that you could go to this. Try to understand the article, read the comments below ...
Still not ROFLING? You must be a JavaScript programmer :-) They've nothing to laugh anymore :-(
For me, I could not stop laughing about these "excellent" comments:
But you're right, it is really serious. Failed communication is the root of all evil, or was it premature optimization?
Whatever, I must find out what happens when I call new
in JavaScript. For anyone knowing that new
is next to the C-language alloc(bytes)
, finding this out must be like receiving the >sign of the times<!
First I try it with an Object as argument:
1 | var someObject = {}; |
So this fails, new
requires a function to be behind it.
1 | var someFunction = function() { |
So, this worked, no error. But what is the return?
1 | console.log("someInstance instanceof Object = "+(someInstance instanceof Object)); |
This outputs:
someInstance instanceof Object = true
someInstance instanceof Function = false
someInstance = [object Object]
someInstance.constructor = function() {
console.log("Could it be that I am a constructor?");
}
someInstance.prototype = undefined
The created thing
Because we can not call new
on Objects, it seems that classes are represented by functions in JavaScript.
To be able to distinguish between functions that create instances and such that do not, some wise people introduced the convention to write constructor-functions capitalized.
1 | var Foo = function(a, b) { |
Now before digging into the "this" keyword, here is a summary of the >sign of the times< (semantics that have gone into the C alloc()
function). The new
keyword ...
__proto__
of that Object to the prototype
of the given function (whatever that means),So keep in mind: when your "constructor" function returns an Object, THAT will be what the new
operation returns! (And you are self responsible whether the instanceof
operator works on it correctly.)
1 | var Animal = function(givenName) { |
This yields:
animal instanceof Animal: false
When looking for explanations of the this
keyword, you can find sentences like
this
is whatever is left of the dotthis
in a function is the Object that called the functionFollowing code refers to the Foo
constructor function above.
1 | var forgotNew = Foo(1, 2); // "this" is the "window" object |
This outputs:
We see that
forgotNew=undefined
A = 1
B = 2
appliedNew.A = 3
appliedNew.B = 4
A = 1
B = 2
new
operator, new
operator, new
operatornew
operator you create unintended global variables! new
. The "this" is an Object, I call it context. Functions are not bound to their objects. Sometimes we do not realize that context changes in JavaScript. Look at following example.
1 | var fooCapsule = { |
This outputs:
We can see that the global variables were not affected by that, still A=1 and B=2.
fooCapsule.A = 5
fooCapsule.B = 6
A = 1
B = 2
But imagine setting a "function pointer" to some encapsulated function and then calling it:
1 | var myFoo = fooCapsule.Foo; |
This outputs:
fooCapsule.A = 5
fooCapsule.B = 6
A = 7
B = 8
We see that the globale A=7 and B=8 were affected now. Why? The function was called by a context that was not the Object the function was defined within. It was called from the browser's window Object, and thus it worked in that context.
This is another aspect of scoping in JavaScript:
When you don't use "this", you won't need "new". Both are not needed when using what I call "factory functions" to create Objects.
1 | var fooFactory = function(a, b, context) { |
This outputs:
We see that the global variables A and B were not affected. And we created new Object instances without using the
fooBar1.A = 9, fooBar1.B = 10
fooBar2.A = 11, fooBar2.B = 12
A = 7
B = 8
new
operator. The only difference between new
and creating Objects by {}
is the "protoype" property, which is set by the new
operator into the new Object. But this plays a role only when modelling inheritance hierarchies. ɔ⃝ Fritz Ritzberger, 2014-09-27