开发者

Confusing JavaScript statement: "var x = new this();"

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开发者_JAVA技巧.

My head has gone off into a complete spin.

Could someone please explain this in detail?


In a javascript static function, you can call new this() like so,

var Class = function(){}; // constructor
Class.foo = function(){return this;} // will return the Class function which is also an object

Therefore,

Class.foo = function(){ return new this();} // Will invoke the global Class func as a constructor

This way you get a static factory method. The moral of the story is, not to forget functions are just like any other objects when you are not calling them.


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.


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.


Imagine the following situation :

var inner = function () {
    var obj = new this;
    console.log(obj.myProperty);
};

var f1 = function () {
    this.myProperty = "my Property"
}

f1.f2 = inner;
f1.f2();

Here the calling object is itself a function, so this will return a function, and we can instantiate it.

In order to use this()(not this) the outer function(the context) must itself return smth that can be instantiated(another function):

var inner = function () {
    var obj = new this();
    console.log(obj.myProperty);
};

var f1 = function () {
    var func = function () {};
    func.myProperty = 'my property';
    return func;
};

f1.f2 = inner;
f1.f2();


A simpler code explaination:

class User {
  constructor() {
    this.name = '';
    this.age = '';
  }
  static getInfo() {
    let user = new this();
    console.log(user);
  } 
}

User.getInfo()

Output:

Object {
  age: "",
  name: ""
}


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...


"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.


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().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜