开发者

How does jQuery hijack "this"?

I'm just curious to know how jQuery is able to hijack the 'this' keyword in Javascript. From the book开发者_JAVA百科 I'm reading: "Javascript the Definitive Guide" it states that "this" is a keyword and you cannot alter it like you can with an identifier.

Now, say you are in your own object constructor and you make a call to some jQuery code, how is it able to hijack this from you?

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

My only guess would be that since you are providing a callback to the jQuery each() function, you are now working with a closure that has the jQuery scope chain, and not your own object's scope chain. Is this on the right track?

thanks


You can change the context of a function (i.e. the this value) by calling it with .call() or .apply() and passing your intended context as the first argument.

E.g.

function fn() {
    return this.foo;
}

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

Note: passing null to either call or apply makes the context the global object, or, in most cases, window.

It's probably worth noting the difference between .apply() and .call(). The former allows you to pass a bunch of arguments to the function it's being applied to as an array, while the latter lets you just add them as regular arguments after the context argument:

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

From the jQuery source:

for ( var value = object[0];
      i < length &&
      callback.call( value, i, value ) // <=== LOOK!
      !== false;
      value = object[++i] ) {}


It doesn't hijack anything - it just makes sure that "this" is pointing at what it wants it to. Look up the standard "call" function that's available for any Javascript function object.


See the documentation for Function.apply. The first parameter is the "context". It can be any object. If null, it will be scoped globally.


The function type in JavaScript has a method called apply() which allows you to specify to what object this is bound at. Its signature is:

apply(thisObj, arguments);

Once called, it calls the function binding this to thisObj and passing the arguments arguments.

It is usually used as such:

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");


try this:

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"
})()


function.apply() and function.call() allow you to change what this points to in Javascript. Here's a couple of handy articles that explain it in greater detail - Scope In Javascript and Binding Scope in Javascript

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜