javascript class problem
Examine this code
var _class=fu开发者_C百科nction()
{
this.Test=100;
this.Callback=function(msg)
{
alert(msg+"\r\n"+this.Test);
}
}
function run(call)
{
call("Hello world");
}
var obj=new _class();
run(obj.Callback);
I got the result :
[Alert]
Hello world
undefined
but when i call obj.Callback("Hello world")
i got expected
[Alert]
Hello world
100
why ?
thank for help
There's no intrinsic relationship between an object and the functions defined "inside" it. The only thing that determines the value of this
(called the "receiving" object) in a function call is the way in which the function is called.
- Call a function with
object.func()
, andthis
will be bound toobject
. - Call a function with "call()" or "apply()", and
this
is determined by the first parameter. - If a function is called without any implicit object context, however, as in your "callback" example, then
this
won't refer toanythingyour object — it will refer towindow
(or whatever the global context is).
The trick is that when you want to use a function as if it were a "method" on an object, such that the relationship remains intact even though the function reference has been yanked away from the object, you can pre-bind this
in a couple of ways:
- You can wrap the function in another function, so that you explicitly retain
this
in a closure. - You can use ".bind()" to (essentially) do the same thing.
The first way would look like this:
run(function() { obj.Callback(); });
The second way would look like this:
run(obj.Callback.bind(obj));
JavaScript is quite different from languages like C# or Java in this respect. In those languages, a function is sort-of stuck forever in a relationship with its class (or instances of its class). Not JavaScript; it really doesn't matter at all, in fact, where a function is defined. Your "_class" function would be equivalent if it were written like this:
function helloThere() {
alert(msg + "\r\n" + this.Test);
}
var _class = function() {
this.Test = 100;
this.Callback = helloThere;
};
edit — @jamietre correctly notes that had your "_class" function contained some var
declarations or local functions, then there most certainly would be a difference (though not with respect to the way this
behaves when "Callback" is invoked).
edit again — Thanks @Koolinc
this.Test is not defined. The scope of this in that context is the callback function.
This is a quick fix:
var _class=function()
{
var self = this;
this.Test=100;
this.Callback=function(msg)
{
console.log(msg+"\r\n"+self.Test);
}
}
精彩评论