What is this?

6003 ワード

(This is an article I wrote several years ago to explain the this keyword in some programming languages. The title is a pun intended.)
Java, C# etc.
The this is a keyword in programming languages such as Java, C# and JavaScript. In the former two class based languages, the value of this is straightforward and simple. It means the current object instantiated with the class definition which contains this. In these languages, this can only be used in a statement within a function i.e. a method of its containing class. It cannot be used in the right side of an initialization statement belonging to the declaration part of the class. A special case is that like other non-static variables this cannot be used in a static method as it doesn't need any instance to be called. Put simply, this only appears in one kind of place and there is only one way in which the containing code is called and thus has just one meaning.
Outside Functions In JavaScriptNow comes our focus --JavaScript. In this prototype based language with great simplicity and ingenuity, the value of
this is a little complicated. It can be used outside or inside a function, and can mean different things in either situation.
As its name implies, JavaScript is a script language. That means it usually shows in the form of snippets embedded in a host (a browser in our discussion)instead of a standalone application. A script snippet consists of statements and functions. This is the current object or context object in the current scope. When this stands in an top level statement outside of any function, it refers to the global object -- the current window object. (Examples used below runs in a Firefox equipped with Firebug)
//Example 1
//A log function to work around the duplicated string issue in the js console
function log(msg){
    if (console)
    {
        console.log(new Date().getTimeString()+' >> '+msg);
    }
}
//get a string form of a Date object
Date.prototype.getTimeString=function() {
    if (!(this instanceof Date))    return;
    var d=":";
    var result=this.getHours()+d+this.getMinutes()+d+this.getSeconds()+d+this.getMilliseconds();
    return result;
}

this.abc = "hello";
log(this); //10:28:4:281 >> [object Window]
log(window.abc); //10:28:4:283 >> hello
log('this is the window? ' + (this==window));  //10:28:4:283 >> this is the window? true

Inside Functions In JavaScriptWhen
this appears in a function, it becomes more interesting. A function in JavaScript is not necessarily bound to a object. Instead a function could be stuck to an object instance or a constructor's prototype object manually or declared as a method in an object literal. Consequently a function can be called either directly or as an object's method. Besides, every function can act as an object constructor. In all these circumstances
this means differently and we cannot be sure about its meaning when the container function is defined until it is called. Below are some examples.
//Example 2
//This might be the most familiar form we meet this where its container function acts as a constructor
function  father(){
this.age=45;
this.howOld=function(){
console.log('I am '+this.age+' years old.');
}
}
var f=new father();
f.howOld();  //prints 'I am 45 years old'

//Example 3
//even a nested function is not bound to the object created with the outer function
function father(){
this.showMe=function(){
inner();
console.log(this);//prints 'Object'
}
function inner(){
console.log(this);  //prints 'Window'
}
}
var f=new father();
f.showMe();

//Example 4
//A function is called first as an object's method then directly
var career='teacher';
function whoAmI(){
console.log('I am a '+this.career);
}
function father(){
this.career='driver';
}
father.prototype.whoAmI=whoAmI;
var f=new father();
f.whoAmI();  //prints 'I am a driver'
whoAmI();  //prints 'I am a teacher'

//Example 5
//changes the above example a little
var career='teacher';
function father(){
this.career='driver';
}
father.prototype.whoAmI=function(){
console.log('I am a '+this.career);
}
var f=new father();
f.whoAmI();  //prints 'I am a driver'
var w=f.whoAmI;
w();  //prints 'I am a teacher'

Now let's show the underlying reason for the diverse meaning of this in JavaScript. Fortunately it's rather simple. This refers to the context object. According to the form in which a function is called, an object may be passed to it explicitly or implicitly. If no object is passed, as we call a function directly, this points to the global object -- window, just like what happens in a top level statement.If an object is passed to the called function, there are two manners.
1. instance.method(parameters)The object instance is passed to the function as the value of this implicitly. We can imagine it in a 'static method' way: object_method(instance, other_parameters). Using instance.method([parameter])makes calling function easier and briefer.2. function object_constructor(parameters){functionbody}var instance=new object_constructor(parameters);An new anonymous empty object is passed to the constructor function as the value of this implicitly. Then we can add properties and methods to it.
Inside Event Handlers In JavaScript
One common usage of functions of JavaScript is to register them as event handlers. In such a function, this refers to the object that fires the event.
//Example 6
//In the function registered as the click event listener of a button, alert the Id of the event publisher via this.
document.getElementById("btnShowMe").addEventListener("click", function() {alert("My Id is " + this.id);}, false); //My id is btnShowMe