2012-04-12 2 views
7

Они взяты из учебников Jquery vid для премиум-класса.
http://tutsplus.com/lesson/the-this-keyword/ Джефф объясняет, что это такое, каждый раз, но я не уверен, что понял их все.4 разных сценария «этого». Какая правильная интерпретация?

E.g. 1

function doSomething(e) { 
e.preventDefault(); 
console.log(this); 
} 

$('a').on('click', doSomething); 

В этом случае «это относится к„а“элемента» (будучи в этом случае родительский объект)

Я предполагаю, что это потому, что здесь утверждение приравнивает к:

$('a').on('click', function (e) { 
    e.preventDefault(); 
    console.log(this); 
    } 

Таким образом, 'a' является материнским объектом

Например 2

var obj = { 
    doIt: function(e){ 
    e.preventDefault(); 
    console.log(this); 
    } 
} 

$('a').on('click', obj.doIt); 

В этом случае «это по-прежнему относится к„а“элемента» (* но, видимо, это не родительский объект?)

Кажется, на этот раз мы вызываем метод, кроме утверждение все равно приравнивается к тому же, что и Eg 1

* Одна вещь в учебнике меня немного смутила. Я думал, что «это» всегда относится к родительскому объекту, поэтому в этом случае «a» все еще является родительским объектом. Но (в 05.23 в учебнике) он говорит, что это не так, заявив, что «могут быть моменты, когда вы хотите« это »ссылаться на его родительский объект, который был бы« obj », в каком случае он создает, например, 3.

E.g. 3

var obj = { 
    doIt: function(){ 
    console.log(this); 
    } 
} 

$('a').on('click', function(e){  
obj.doIt(); 
     }; 
e.preventDefault(); 

В этом случае «это относится к OBJ объекта»

Я полагаю, что это с тем, что «это» находится в вложенной функции, как это утверждение эквивалентно:

$('a').on('click', function(){  
function(){ console.log(this);} 
}; 
e.preventDefault(); 

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

ЭГ4

var obj = { 
    doIt: function(){ 
    console.log(this);  
    } 
} 

$('a').on('click', function(e){  
     obj.doIt.call(this);    
     e.preventDefault(); 
}); 

В этом случае «Это относится к„а“»

Согласно Javascript Definitive Guide «Первый аргумент как вызов() является объект, на котором функция должна быть вызвана » Здесь« это »используется как первый аргумент. Но «это» не является объектом, на который должна вызываться функция?
Я думаю, что я получаю, что функция вызова есть, чтобы вызвать функцию и использовать свой первый параметр как указатель на другой объект, но я не понимаю, почему использование 'this' означает, что функция вызывается 'a'. Это не то, что я видел в других вызовах().

Извините за такой мамонт.Надеюсь, кто-то еще читает эту сцену ...

+0

+1 потому что мне слишком поздно начинать отвечать к этому замечательному вопросу. Несомненно, кто-то еще скоро - это жизненно важный момент и тот, который, как правило, плохо освещен в учебниках JS. – jimw

+3

* «Я думал, что« это всегда относится к родительскому объекту ... »* Нет, не думайте о' this' как о родительском объекте. Подумайте об этом как о вызывающем контексте *, значение которого может быть задано несколькими различными способами, одним из которых является вызов метода из объекта. –

ответ

4

Надеюсь, это поможет прояснить проблему, это может сбить с толку.

  • Когда this ослаблен на код, он будет ссылаться на глобальный объект (в веб-браузерах, то есть window).

    console.log(this); // window 
    
  • Когда this находится внутри метода объекта (например, на вашем Э.Г. 3), он будет ссылаться на объект. Это относится к объектам, созданным с помощью new, или как литералы объектов (например, на вашем примере).

    var obj = { 
        doIt: function(e){ 
         console.log(this); 
        } 
    } 
    obj.doIt(); // obj 
    
  • Внутри обработчика события, this будет ссылаться на объект событие, связанного с.

    // This is the plain js equivalent of your jQuery example 
    document.getElementsByTagName['a'][0].addEventListener('click', function(e){ 
        console.log(this); // the first anchor on the document 
    }); 
    
    // This is exactly the same: 
    var clickHandler = function(e){ 
        console.log(this); // the first anchor on the document 
    }; 
    document.getElementsByTagName['a'][0].addEventListener('click', clickHandler); 
    
    // Even if the handler is defined inside of another object, this will be 
    // the obj the event is bound to. It's the case of your E.g. 2 
    var obj = { 
        doIt: function(e){ 
         console.log(this); // the first anchor on the document 
        } 
    } 
    document.getElementsByTagName['a'][0].addEventListener('click', obj.doIt); 
    // When you pass obj.doIt to addEventListener above, you are passing a reference 
    // to that function. It's like "stealing" the function from the object 
    
  • Когда объект передается в качестве первого параметра Function.call или Function.apply, если this появляется внутри функции он будет ссылаться на объект, который вы прошли. Это способ заставить то, на что указывает this.

    var obj = { 
        doIt: function(){ 
         console.log(this); // window 
        } 
    } 
    obj.doIt.call(window); 
    
+0

Однако, если 'obj' с функцией' doIt', если мы делаем 'var fn = obj.doIt; fn() ',' this' будет ссылаться на 'window' внутри' fn'. –

+0

Да, как и в моем примере с 'addEventListener' (за исключением того, что в этом случае он будет указывать на узел DOM, а не' window'). Но логика такая же. – bfavaretto

0

Путь this ведет себя в JavaScript, сначала немного запутанный. В основном, в отличие от переменных (которые статически охвачены областью), this является динамически областью. Точка, значение this определяется путем где вызывает функцию вместо того места, где вы ее написали.

Когда вы передаете свою функцию on, она позже вызывается из контекста, где this является элементом, о котором идет речь. Это происходит независимо от того, как вы получили эту функцию. То есть функция не заботится о том, получаете ли вы ее с помощью синтаксиса, например obj.fn, или просто его имя fn - значение выражения в обоих случаях одинаково.

С вещами, отличными от функций, это имеет смысл. Дано:

var a = 10, 
    obj = { a : 10 }; 

вы согласитесь, что выражения a и obj.a имеют одинаковое значение. Это также относится к функциям.

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

+3

Мы не должны путать 'this' с« scope ». Они полностью разделены. И 'this' не определяется * где *, а скорее * как * функция вызывается. –

+0

Присмотревшись, есть несколько вещей не так. Как ... * "... позже он вызывается из контекста, где это элемент, о котором идет речь" *. Это не имеет значения. Передача включенного контекста в вызываемый отсутствует, если вы не вручную перенесите его с помощью '.call()' или '.apply()'. И это ... * «... функция не заботится о том, обращаетесь ли вы к ней с помощью синтаксиса типа« obj.fn »или просто его имя« fn' »* ... тоже не так. Это очень важно. –

+0

Моя точка зрения заключалась в том, что выражение 'f' и' obj.f' имеет одно и то же значение (до тех пор, пока 'f' и' obj.f' указывают на ту же функцию). Возможно, я не был достаточно ясен. Что касается другого момента, вы можете изменить значение 'this' без' call' или 'apply', поместив функцию в объект. Поэтому, если вы * вызываете * это из объекта или по себе, но для его доступа (получения функции как значения) это не имеет значения. –

0

Действительно оценить эти ответы, ребята. Я опубликовал в начале hrs и попробовал (&), чтобы взять немного времени, чтобы переварить ваши отзывы.

https://developer.mozilla.org/en/JavaScript/Reference/Operators/this был отличным криком. Я читал немало статей/статей, и этот кажется одним из лучших.

Я думаю, что главным просветлением было то, что объект, связанный с этим, определяется тем, как/где функция была вызвана (вызывающий контекст), а не как и где была определена функция.

Так просто вернуть вещи в Q & область применения и попытаться ответить на мой собственный Q в свете того, что вы, ребята ответили ...

Э.Г. 1 Здесь: функция «DoSomething» была названа в контексте обработчика щелчка так объект, связанный с «это» есть «»

Э.Г. 2 Опять обработчик щелчка по-прежнему вызывая функцию таким образом объект привязан к «это» есть «»

Э.Г. 3 В вложенной функции вызывающий контекст - obj.doIt(). Итак, как он говорит в учебнике, объект, привязанный к «этому», является «obj».

Хотя, на основе аналогичной логики от developer.mozilla.org пример ниже, не является объектом действительно связан с «obj.doIt»:

o.b = {g: independent, prop: 42};   
console.log(o.b.g()); // logs 42   

«это связывание зависит только наиболее немедленная ссылка-член ... это внутри функции будет ссылаться на ob. Тот факт, что объект сам является членом o, не имеет никакого значения, самая важная ссылка - это все, что имеет значение ».

E.g. 4

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

Я надеюсь, что это немного ближе. Я чувствую себя как тупик на этом (страшный каламбур), потому что ответы представленный мне, но я все еще не полностью уверен в том, что я прибиваю концепцию.

Если мне нужно ползти обратно в мою дыру какое-то время, чтобы переварить, я молюсь о новом статусе, обрушивая курсор Javascript & JQuery для просто через несколько недель.

Еще раз спасибо за отзыв.

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