this in JavaScript in detail

  Peter        2013-05-09 18:35:12       3,350        0    

this in JavaScript is always confusing, it is one of the most frequently seen traps in JavaScript. this is not a good design in JavaScript(You can refer some other design flaws of JavaScript here), since it's lazy binding feature, it can be a global object, the current object or.... Some people even avoid using this in JavaScript.

Actually if you master how this works, then you will know how to stay away from these traps. Let's take a look at what this points to in below situations.

1. In global scope codes

alert(this)//window

this will point to global object(usually it's window in web browsers) in global scope codes.

2. In a pure function call

function fooCoder(x) {
	this.x = x;
}
fooCoder(2);
alert(x);// Global variable x's value is 2

Here this is also pointing to the global object since the function defined in global scope is actually one method of the global object. So this will be the global object. In strict mode, this will be undefined.

3. In a method call of an object

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		console.log(this.name + " says " + sth);
	}
}
person.hello("hello world");

The output will be "foocoder says hello world". this will point to the person object, i.e, the current object calling the method.

4. In a constructor

new FooCoder();

In a constructor this will points to the newly created object with new.

5. In a private function call

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		var sayhello = function(sth) {
			console.log(this.name + " says " + sth);
		};
		sayhello(sth);
	}
}
person.hello("hello world");//clever coder says hello world

In a private function, this is not binding the outer method's object, instead it's binding to the global object. This is considered as the design flaw of JavaScript because no one wants the this in the private function points to the global object here. The general solution is assign this to another variable and refer that variable in the private function.

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		var that = this;
		var sayhello = function(sth) {
			console.log(that.name + " says " + sth);
		};
		sayhello(sth);
	}
}
person.hello("hello world");//foocoder says hello world

6. In call() or apply()

person.hello.call(person, "world");

apply() and call() are similar, the only difference is the parameters passed in after the first parameter. In apply(), other parameters will be passed with an array, while in call(), other parameters are passed in separately.

call( thisArg [,arg1,arg2,… ] );  // Parameter list,arg1,arg2,...
apply(thisArg [,argArray] );     // Parameter list,argArray

The first parameter passed in is the object which this will point to. We can specify any object which to be point to by this.

7. Other

We may see below code frequently:

$("#some-ele").click = obj.handler;

If we use this in the handler, will this bind to obj? Obviously not, after the assignment, the functions is called in the callback function, this will bind to the $("#some-div") element. This is what we need to understand here--execution context. 

Then how do we specify the this object to be what we want in the callback function? In ECMAScript 5, there is a bind() method:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg will be the this object we want to be.

$("#some-ele").click(person.hello.bind(person));

Now this will be the person object

In Prototype.js we can find the implementation of bind():

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
};

Conclusion

1. When function is called as a method of an object, this will point to that object

2. When in a pure function call, this will be the global object(in strict mode, this will be undefined)

3. In a constructor, this will be the newly created object

In one sentence, this will always points to the object which the function is called on.

Reference : http://foocoder.com/blog/xiang-jie-javascriptzhong-de-this.html/

JAVASCRIPT  THIS  BIND 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Is this a workaround?