Непонятное утверждение JavaScript: "var x = new this ();" - PullRequest
15 голосов
/ 13 августа 2010

Я думал, что понял концепцию объекта-прототипа JavaScript, а также [[proto]], пока не увидел несколько постов, касающихся наследования классов.

Во-первых, «JavaScript OOP - умный способ» вhttp://amix.dk/blog/viewEntry/19038

См. Раздел реализации:

var parent = new this('no_init');

А также «Простое наследование JavaScript» в великолепном блоге Джона Резига.

var prototype = new this();

Что означает new this();на самом деле значит?

Это утверждение не имеет смысла для меня, потому что я понимаю, что this указывает на объект, а не на функцию конструктора.Я также пытался протестировать операторы в Firebug, чтобы понять это, и все, что я получаю, это синтаксические ошибки.

Моя голова полностью завершилась.

Может кто-нибудь объяснить это вдеталь

Ответы [ 7 ]

5 голосов
/ 13 августа 2010

Я думаю, что вас смущает именно то, откуда на самом деле исходит "это".Так что потерпите меня - вот очень краткое объяснение, которое, я надеюсь, прояснит это.

В JavaScript то, на что «это» ссылается в функции, всегда определяется во время вызова функции.Когда вы делаете:

jimmy.nap ();

Функция nap (метод) запускается и получает jimmy как "this".

Какие объекты имеют ссылки на napне имеет значения.Например:

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!

Другими словами, всякий раз, когда у вас есть:

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);

Во что это «переводится» (не буквально - это педагогически, а не о том, как интерпретаторы JavaScript)на самом деле работает вообще) это что-то вроде:

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);

Итак, обратите внимание, как расширение используется в примере на этой странице:

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

Проверка вопроса: когда расширяется, что делаетэто думает "это" относится к?Ответ: это верно.«Персона».

Значит, загадочный код на самом деле такой же, как (в данном конкретном случае):

var prototype = new Person('no_init');

Уже не так таинственно, а?Это возможно, потому что, в отличие от некоторых языков, переменная JavaScript, в том числе «this», может содержать любое значение, включая такую ​​функцию, как Person.

(Нет ничего, что делает Person конкретно конструктором. ЛюбойФункция может быть вызвана с новым ключевым словом. Если я вспоминаю точную семантику, я думаю, что когда функция вызывается с новым ключевым словом, ей автоматически присваивается пустой объект ({}) в качестве контекста («this»)и когда функция возвращается, возвращаемое значение является тем же объектом, если (возможно?) функция не возвращает что-то еще)

Это крутой вопрос, потому что он говорит с довольно важной частью аккуратности или странности JavaScript (в зависимости ото том, как вы это видите).

Это отвечает на ваш вопрос?Я могу уточнить, если это необходимо.

5 голосов
/ 13 августа 2010

AJS.Class эффективно * переводит это:

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

в это:

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;

Следовательно, в этом случае this в AJS.Class.prototype.extend относится к Personпотому что:

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

* Есть много случаев, которые я не рассматриваю;это переписано для простоты понимания проблемы.

3 голосов
/ 13 августа 2013

В функции javascript static вы можете вызвать new this() примерно так:

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

Следовательно,

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

Мораль этой истории - не забыватьфункции, как и любые другие объекты, когда вы их не вызываете.

3 голосов
/ 22 февраля 2013

Представьте себе следующую ситуацию:

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

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

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

Здесь вызывающий объект сам является функцией, поэтому this вернет функцию, и мы можем создать ее экземпляр .

Чтобы использовать this () (не this ), внешняя функция (контекст) должна сама возвращать что-то, что может быть создано (другая функция):

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();
0 голосов
/ 13 августа 2010

this () относится к функции, в которой находится код, но this () должна быть внутри этой функции. Вызов нового this (); внутри функции создаст бесконечный цикл. Вызов его вне функции был бы излишним, потому что не задана функция / класс, как this ().

0 голосов
/ 13 августа 2010

«this» означает контекст функции, запущенной в данный момент.

Код, который вы публикуете, обязательно появляется в функции, которая действует как метод для объекта.Таким образом, объект является контекстом функции.

"new this ()" вернет клон текущего объекта после запуска его функции конструктора с переданными аргументами.

0 голосов
/ 13 августа 2010

см. Эту ссылку http://www.quirksmode.org/js/this.html Он расскажет вам об этом ключевом слове, но я не уверен, что это (), это может быть какая-то пользовательская функция ...... не в курсе ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...