只要牢牢记住一点:this指向函数的调用者。
最典型的例子:

var obj = { a:1, fn:function(){ alert(this.a); } }
obj.fn();

此时,fn的调用者是obj,所以fn中的this指向obj,所以显示为obj.a。再看:

var a = 2;
var obj = { a:1, fn:function(){ alert(this.a); } }
obj.fn.call(window);

第一行的a,就是等于2的那个,是属于window域的,call会改变调用者,在这里,obj.fn将调用者更改为window,所以this指向window,所以将显示为window.a。

var a = 2;
var fn = function(){ alert(this.a); }
fn();

这里,fn也是window域的,所以,其实是在执行window.fn(),那么,调用者为window,所以显示window.a。

下面说一下js创建对象的方式,常用的,如下面这个样子:

function o(){  };
o.prototype = {
  value : 1,
  fn : function(){ alert(this.value); }
}
var a = o();
var b = new o();

这里,a仅仅是返回o()的返回结果,与o.prototype没有任何关系。而o内部又没有返回任何值,所以a是undefined。这是一个容易混淆的地方。
b使用了new,那么b成为o.prototype的一个指针。那么,b.fn()的时候,实际就是o.prototype.fn(),fn的调用者是o.prototype,所以fn内部的this指向o.prototype,所以fn内部的this.value就是o.prototype.value。

以上内容不考虑个别浏览器bug。