views:

119

answers:

5

Hi everyone,

I thought I understood the concept of the JavaScript prototype object, as well as [[proto]] until I saw a few posts regarding class inheritance.

Firstly, "JavaScript OOP - the smart way" at http://amix.dk/blog/viewEntry/19038

See the implementation section:

var parent = new this('no_init');

And also "Simple JavaScript Inheritance" on John Resig's great blog.

var prototype = new this();

What does new this(); actually mean?

This statement makes no sense to me because my understand has been that this points to an object and not a constructor function. I've also tried testing statements in Firebug to figure this one out and all I receive is syntax errors.

My head has gone off into a complete spin.

Could someone please explain this in detail?

A: 

see this link http://www.quirksmode.org/js/this.html It will tell you about the this keyword, but I am not sure what this() is, may be its some kind of user defined function...... that you are not aware of...

Starx
`new this()` is just like `var MyClass = this; new MyClass()`. There's nothing special about the `this()` in `new this()`.
strager
Oh...... I didn't knew that thanks
Starx
A: 

"this" means the context of the function currently running.

The code you are posting surely appears in a function that act as a method for an object. So the object is the context of the function.

"new this()" will return a clone of the current object after running its constructor function with the passed arguments.

Sebastián Grignoli
A: 

this() refers to the the function that the code is in, but this() would have to be within that function. Calling new this(); within a function would create a never ending loop. Calling it outside of a function would be redundant because there is no function/class set as this().

BigRossLabs
The looping would be completely dependent on the context, `this` doesn't *necessarily* refer to the current function, it does refer to the current object's definition in this case because we're in the prototype of an object, but say in an event handler `this` doesn't refer to the current function at all.
Nick Craver
Yes; `this` is bound by the call, and not when the function is created. Otherwise, delegation through prototypes couldn't function properly!
strager
+4  A: 

AJS.Class effectively* translates this:

var Person = new AJS.Class({
    init: function(name) {
        this.name = name;
        Person.count++;
    },
    getName: function() {
        return this.name;
    }
});
Person.count = 0;

into this:

var Person = function (name) {
    this.name = name;
    Person.count++;
};

Person.prototype = {
    getName: function() {
        return this.name;
    }
};

Person.extend = AJS.Class.prototype.extend;
Person.implement = AJS.Class.prototype.implement;

Person.count = 0;

Therefore, in this case, this in AJS.Class.prototype.extend refers to Person, because:

Person.extend(...);
// is the same as
Person.extend.call(Person, ...);
// is the same as
AJS.Class.prototype.extend.call(Person, ...);

* There are a lot of cases I don't go over; this rewrite is for simplicity in understanding the problem.

strager
Your help throughout this question has been amazing strager. Thanks a lot, I really appreciate it :).Before I mark this as an answer- I'm hoping you can give a confirmation of my understanding. Essentially, <code>this<code> still "refers" to a Function object in extend() (e.g. function Person() as above). It is NOT an non Function object.
@user419125, Hmm? I'm not quite following what you're saying here. A `Function` is an `Object`; it's a special type of `Object` (a "subclass", if you will, with some other special semantics).
strager
+1  A: 

What is confusing you, I think, is just where "this" is really coming from. So bear with me-- here is a very brief explanation that I hope will make it quite clear.

In JavaScript, what "this" refers to within a function is always determined at the time the function is called. When you do:

jimmy.nap();

The nap function (method) runs and receives jimmy as "this".

What objects have references to nap is irrelevant. For example:

var jimmy = {}, billy = {};
jimmy.nap = function(){ alert("zzz"); };
var jimmy_nap = jimmy.nap;
jimmy_nap(); // during this function's execution, this is *NOT* jimmy!
             // it is the global object ("window" in browsers), which is given as the 
             // context ("this") to all functions which are not given another context.
billy.sleep = jimmy.nap;
billy.sleep(); // during this function's excution, this is billy, *NOT* jimmy
jimmy.nap(); //okay, this time,  this is jimmy!

In other words, whenever you have:

var some_func = function(arg1, arg2){ /*....*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(2, 3);
other_obj.some_meth(2, 3);

What it's getting "translated" into (not literally-- this is pedagogical, not about how javascript interpreters actually work at all) is something like:

var some_func = function(this, arg1, arg2){ /* ...*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(obj, 2, 3);
other_obj.some_meth(other_obj, 2, 3);

So, notice how extend is used in the example on that page:

UniversityPerson = Person.extend({ /* ... */ });

Pop quiz: When extend runs, what does it think "this" refers to? Answer: That's right. "Person".

So the puzzling code above really is the same as (in that particular case):

var prototype = new Person('no_init');

Not so mysterious anymore, eh? This is possible because unlike in some languages, a JavaScript variable-- including "this"-- can hold any value, including a function such as Person.

(There is nothing that makes Person specifically a constructor. Any function can be invoked with the new keyword. If I recall the exact semantics, I think they are that when a function is called with the new keyword, it is automatically given an empty object ({}) as its context ("this") and when the function returns, the return value is that same object unless (maybe?) the function returns something else)

This is a cool question because it speaks to a pretty essential part of JavaScript's neatness or oddness (depending on how you see it).

Does that answer your question? I can clarify if necessary.

Domingo Galdos
The constructor function is given an empty object with `prototype` members filled (in short). Also, while your conclusion is correct (that `this` is bound to `Person`), how does `Person.extend` end up to be the value of `AJS.Class.prototype.extend`? (I know the answer; I'm just saying you didn't mention it in your answer.)
strager