Как jQuery угоняет это? - PullRequest
       28

Как jQuery угоняет это?

8 голосов
/ 05 февраля 2010

Мне просто интересно узнать, как jQuery может перехватить ключевое слово this в Javascript. Из книги, которую я читаю: «Javascript the Definition Guide» говорится, что «this» является ключевым словом, и вы не можете изменить его, как вы можете с помощью идентификатора.

Теперь, скажем, вы находитесь в своем собственном конструкторе объектов и делаете вызов некоторому коду jQuery, как он может отнять это у вас?

function MyObject(){
    // At this point "this" is referring to this object
    $("div").each(function(){
        // Now this refers to the currently matched div
    });
}

Мое единственное предположение заключается в том, что, поскольку вы предоставляете обратный вызов функции jQuery each (), вы теперь работаете с замыканием, которое имеет цепочку областей действия jQuery, а не цепочку областей действия вашего собственного объекта. Это на правильном пути?

спасибо

Ответы [ 6 ]

16 голосов
/ 05 февраля 2010

Вы можете изменить контекст функции (то есть значение this), вызвав ее с помощью .call() или .apply() и передав в качестве первого аргумента предполагаемый контекст.

* 1006 Е.Г. *

function fn() {
    return this.foo;
}

fn.call({foo:123}); // => 123

Примечание: передача null в call или apply делает контекст объектом global, или, в большинстве случаев, window.

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

someFunction.apply( thisObject, [1,2,3] );
someFunction.call( thisObject, 1, 2, 3 );

Из источника jQuery :

for ( var value = object[0];
      i < length &&
      callback.call( value, i, value ) // <=== LOOK!
      !== false;
      value = object[++i] ) {}
1 голос
/ 05 февраля 2010

function.apply () и function.call () позволяют вам изменять то, на что this указывает в Javascript. Вот пара полезных статей, которые объясняют это более подробно - Scope In Javascript и Binding Scope в Javascript

1 голос
/ 05 февраля 2010

попробуйте это:

var MyObject = { "Test": "Hello world!" };
(function ()
{
    alert(this.Test); // Gives "Hello world!"
}).call(MyObject);

(function ()
{
    alert(this.Test); // Gives "Hello world!"
}).apply(MyObject);

(function ()
{
    alert(this.Test); // Gives "undefined"
})()
1 голос
/ 05 февраля 2010

Тип function в JavaScript имеет метод с именем apply(), который позволяет указать, к какому объекту привязан this. Его подпись:

apply(thisObj, arguments);

После вызова вызывается функция привязки this к thisObj и передача аргументов arguments.

Обычно используется как таковой:

function product(name, value)
{
  this.name = name;
  if (value > 1000)
    this.value = 999;
  else
    this.value = value;
}

function prod_dept(name, value, dept)
{
  this.dept = dept;
  product.apply(this, arguments);
}
prod_dept.prototype = new product();

// since 5 is less than 1000 value is set
var cheese = new prod_dept("feta", 5, "food");

// since 5000 is above 1000, value will be 999
var car = new prod_dept("honda", 5000, "auto");
1 голос
/ 05 февраля 2010

См. Документацию для Function.apply. Первый параметр - это «контекст». Это может быть любой объект. Если ноль, он будет глобально ограничен.

1 голос
/ 05 февраля 2010

Он ничего не угоняет - он просто гарантирует, что «это» указывает на то, что он хочет. Найдите стандартную функцию «call», которая доступна для любого объекта функции Javascript.

...