2016-11-11 3 views
2

Пытаясь понять this, нашел пример в javascript the good parts книге:Понимать `this` в вызов конструктора Pattern

var first; 
var second; 

var Quo = function(string) { 
    first = this; 
    this.status = string;// first this 
}; 

Quo.prototype.get_status = function() { 
    second = this; 
    return this.status;//second this 
}; 

var myQuo = new Quo("confused"); 
console.log(myQuo.get_status()); 

console.log((first===second) + ',' + (second===myQuo) + ',' + (first===myQuo)); 

Выход:

$ node test.js 
confused 
true,true,true 

ли первый this и второй this как пункт myQuo? Как распечатать имя объекта или имя функции или имя класса, на которое указывают this? (Действительно смущен this в настоящее время.)

UPDATE

Другими вопросы: Оба this относятся к экземпляру Quo вместо прототипа Quo в?

Кроме того, пытаясь:

console.log(myQuo.get_status()); 
console.log(first.constructor.name); 
console.log(first); 
console.log(second); 

Выход:

confused 

{ status: 'confused' } 
{ status: 'confused' } 

Почему first.constructor.name ничего? Почему first является { status: 'confused' }?

+0

'this' означает экземпляр внутри конструктора. – dandavis

+2

@ dandavis Они все должны указывать на один и тот же экземпляр 'myQuo'. Ваш комментарий на самом деле не имеет смысла –

+0

Что это за первый и второй? На какие из них вы ссылаетесь? –

ответ

2

В JavaScript, когда функция, определенная на прототипе называется на экземпляре; «this» внутри функции означает (думаю, что он заменен) - этот экземпляр (или объект-владелец, имеющий прототип в цепочке прототипов).

В вашем случае конструктор (который также является функцией прототипа) вызывается с вновь созданным объектом как «это» с ключевым словом «новое».

var Quo = function(string) { 
    first = this; //this is the newly created instance 
    this.status = string;// first this 
}; 

Затем сначала присваивается тот же экземпляр.

Когда get_status вызывается в том же экземпляре, это снова заменяется экземпляром;

Quo.prototype.get_status = function() { 
    second = this; //this is myQuo 
    return this.status;//second this 
}; 

и на этот раз второй присваивается тот же экземпляр.

Выполнение myQuo.get_status() такое же, как;

Quo.prototype.get_status.call(myQuo) 

Поэтому эти два «этих» ключевых слова относятся к одному и тому же объекту.

Выполнение проверки «===» отлично подходит для сравнения, если две переменные указывают на один и тот же экземпляр. Как получить имя конструктора, просто скажите, что они были сконструированы с конкретным именем конструктора, а не иначе. Можно создать два разных объекта с одним и тем же именем конструктора.

+0

оба 'this' относятся к экземпляру Quo вместо прототипа Quo? – BAE

+0

Да, они относятся к экземпляру. –

+0

Точно. Подумайте о вызове функций прототипа с помощью .call или .apply с экземпляром объекта как «это». –

1

Имеет ли первое это и второе это оба пункта для myQuo?

Исправить, они оба указывают на один и тот же экземпляр Quo.

Как распечатать имя или имя объекта или имя класса, к которому относится каждая эта точка?

console.log(first.constructor.name); 
console.log(second.constructor.name); 
2

Этот вопрос относится только к this и context в JavaScript.

Всякий раз, когда вы задаете вопрос Что такое this? Вы должны всегда задавать себе эти 4 вопроса (по порядку), и вы всегда получите ответ.

  1. Была ли функция вызвана с ключевым словом new?

    Пример: var myObj = new Obj();

    Это: Вновь созданный объект

  2. Была функция вызывается с call, apply или bind с this контекста явно прошло?

    Пример: myFunction.call(self)

    Это: this внутри MyFunction будет равен self

  3. Была функцию называется через /, содержащий объект, владеющий?

    Пример: myObj.myFunction()

    Это: this внутри MYFUNCTION будет равна myObj

  4. Что такое по умолчанию this контекст?

    Это: Если в строгого режима, по умолчанию неопределенными. Если не в строгом режиме, по умолчанию является глобального объектом

Таким образом, в вашем случае:

first = this находится внутри функции Quo, и вызывается с помощью «нового» ключевого слова, поэтому first будет равен вновь созданному объекту.

myQuo просто возвращаемое значение выполнения функции Quo с «новым» ключевым словом, которое возвращает вновь созданный объект по умолчанию, так что почему first === myQuo

second = this внутри функций get_status(), что означает, ничего, пока функция не будет вызвана. Как только функция вызывается, вы можете увидеть вопрос 3 выше, чтобы увидеть, что контекст this будет связан с объектом-владельцем.Поскольку он был вызван с myQuo.get_status(), myQuo является собственником, поэтому second === myQuo.

Надеюсь, это очистит все! Дайте мне знать, если вам нужно дополнительное объяснение!

+0

P.S.У меня есть эти 4 вопроса, написанные на липкой ноте, которая постоянно сидит на моем мониторе для справки - довольно удобно! – mhodges

+0

4. Сложно. _Am Я выполняю строгий режим? Контекст: по умолчанию будет глобальный объект (кроме строгого режима) _ Как запустить строгий режим, кроме строгого режима? Также пример не завершен. –

+0

@AliNaciErdem Ваш комментарий довольно придирчив, если честно .. особенно пример строгого режима является неполным. Я не здесь, чтобы объяснить, как работает строгий режим. Однако я повторил вопрос, чтобы устранить любую двусмысленность. – mhodges

0

Вот объяснение того, как this работает в двух случаях, о которых вы упомянули. Во-первых, вы должны понимать, что this устанавливается в зависимости от того, как называется функция (если только мы не имеем дело с fat arrow functions)

При вызове new

var myQuo = new Quo("confused"); 

Это в основном так же, как делают

var myQuo = Object.create(Quo.prototype); 
// Explicitly setting `this` 
Quo.call(myQuo, "confused") 

При вызове функции на объекте

myQuo.get_status() 

Подразумевает, что функция get_status будет вызываться с помощью того, что находится слева от ., то есть myQuo.

  • Вы никогда не можете теперь имя объекта (если вы имеете в виду, что это называется myQuo)
  • Чтобы получить ссылку на функцию конструктора, вы можете сделать myQuo.constructor (или this.constructor). Если ваша функция названа (как ваша), вы можете использовать this.constructor.name, чтобы получить Quo.
+0

В вашем ответе отсутствует полнота, опустив вызов, примените, привяжите и задайте этот контекст – mhodges

+0

@mhodges Но мой ответ объясняет, что я говорю только о случаях, упомянутых в OP, я не пытался дать подробное объяснение, так как ваш ответ ;) 'Вот объяснение того, как это работает в двух случаях, о которых вы говорили. Я только добавил этот комментарий к вашему ответу, потому что вы сделали подробное объяснение. –

Смежные вопросы