2016-04-13 6 views
4
function wrap(func) { 
    console.log('0', this) 
    return function x() { 
    console.log('1', this) 
    func() 
    return function z() { 
     console.log('3', this) 
    } 
    } 
} 

var obj = { 
    x: 5, 
    test: wrap(function y() { 
    console.log('2', this) 
    }) 
} 

obj.test()() 

Код выше регистрируетОбъяснение для изменения значения `this` в следующем фрагменте кода?

// 0 Window 
// 1 Object 
// 2 Window 
// 3 Window 

У меня возникли проблемы с пониманием того, что диктует, что значение this должно быть.

// 0 Window имеет смысл, потому что это, когда обертка первый называется, и в этот момент его значение this не должно быть установлено в obj

// 1 Object имеет смысл obj.test теперь равен function x(), который должным образом регистрирует this в obj

// 2 Window Я не уверен, почему это происходит. Почему значение this не распространяется на func()? Я думал, что this должен был ссылаться на владельца функции. Означает ли это, что хотя function y() был создан внутри obj, это было как-то поднято к окну?

// 3 Window Аналогично с function z() почему значение this не передавалась от function x(). Разве не должно быть значение this?

+0

Я верю, что с 'func' передается функции' wrap', он получит то же значение 'this', что и' this' внутри 'wrap'. –

+0

Что касается функции 'z', она выполняется внутри глобальной области, поэтому имеет смысл, что ее значение' this' является 'window'. –

+3

Yehuda Katz написал довольно хорошее сообщение в блоге об этой теме: http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/ –

ответ

0

следующим, основном точного руководства this статьи, в порядке, функция вызывает desugar к

  • wrap.call(window, function() {})
  • obj.test.call(obj)
  • y.call(window)
  • z.call(window)

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

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

function wrap(func) { 
    return() => { 
    console.log(this) 
    return() => { 
     console.log(this) 
     func() 
     return() => console.log(this) 
    } 
    } 
} 

это desugars к

function wrap(func) { 
    var _this = this; 

    return function() { 
    console.log(_this); 
    return function() { 
     console.log(_this); 
     func() 
     return function() { 
     return console.log(_this); 
     }; 
    }; 
    }; 
} 

и показывает, что вы должны явно передать вниз значение this. Хотя даже с функциями стрелок важно отметить, что вызов func не сохранит значение this. Для этого мне нужно будет сделать func.call(this).

0

«Это» привязка очень сбивает с толку. Однако, если вы помните эти следующие правила, это будет легче понять. По Javascript документов, есть четыре правил для «это» связывает в этих заказах:

  1. нового оператор
  2. явно или жесткий связывания с помощью вызова или применять методы
  3. неявных связывание с содержащей объект, как метод объекта
  4. по умолчанию (глобального)

из ваших сценариев, только правила # 3 и # 4 не применяются, потому что нет никаких новых операторов и вызвать или применять методы.

Так что объяснения:

// 0 Окна - правило № 4 по умолчанию (глобальное)

// 1 Объект - правило # 3 неявное связывание с содержащим объектом, как метод объекта, OBJ.тест в вашем случае

// 2 Window - правило № 4 по умолчанию (глобального)

// 3 Window - правило № 4 по умолчанию (глобальное)

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