2

Имеется следующий код:

function greet() {
  console.log('Greet', this);
}

let person = { name: "John", sayHi: greet, sayHiWindow: greet.bind(this) }

person.sayHiWindow()

Возник вопрос: почему при вызове person.sayHiWindow() в консоли выдаёт объект window, а не person?

Pavel
  • 101

2 Answers2

2

Потому что в этом месте

sayHiWindow: greet.bind(this)

this - это window, а person еще не существует..

  • а из-за чего this - это window? где-то нашёл, что это за счёт, что this формируется при вызове функции, но если даже в функции greet сделать возврат строки, а в person указать не bind, а call, то всё равно получится ссылка на объект window. и в каком плане "person еще не существует"? вызов происходит после объекта person – Pavel Jul 12 '20 at 13:32
  • @Pavel Я не понимаю, что Вы говорите. Какой возврат строки? –  Jul 12 '20 at 13:40
  • К примеру, если в функции greet будет не console.log, а, допустим, return 'Greet'. – Pavel Jul 12 '20 at 14:01
  • @Pavel Я не понимаю, что Вы говорите. Покажите код. –  Jul 12 '20 at 14:05
2

Тут стоит помнить, что this равняется субъекту вызова метода, если упоминается внутри метода, в теле функции, в её области видимости. Когда вы определяете sayHiWindow: greet.bind(this), вы присваиваете ключу sayHiWindow значение, возвращаемое функцией greet.bind(this), и здесь this вы используете вне тела метода, как аргумент вызова функции, и вы находитесь в глобальной области видимости, где this равно window.

То, чего вы пытаетесь добиться, можно реализовать так:

sayHiPerson : function() { greet.bind(this)(); },
vsemozhebuty
  • 14,042
  • если утрированно, то можно считать, что, скажем так, внутри объекта person this - это window, но внутри методов this равен объекту, в контексте которого он был вызван? – Pavel Jul 12 '20 at 15:23
  • 1
    "внутри методов this равен объекту, в контексте которого он был вызван" — да, если никаких дополнительных аномалий (вроде bind) не было. "внутри объекта person this - это window" — не всегда: во-первых, «внутри объекта» — не очень чёткое понятие (внутри метода объекта это ведь тоже внутри объекта), но допустим мы имеет в виду определение ключей литерала объекта: тогда this будет window только вне контекста других методов и только в определённом окружении (в браузере); но если объект создаётся в области видимости другого метода, this уже может быть объектом окружающего метода. – vsemozhebuty Jul 12 '20 at 15:37