1.函数调用:this指向window,返回值由return决定

function f1() {
    console.log(this);
}
f1();       //window

2.方法调用(函数作为方法调用):this指向方法的调用者  ,返回值由return决定

var obj = { 
  hello: function() { 
    return "hello, " + this.username; 
  }, 
  username: "Hans Gruber"
};
obj.hello(); // "hello, Hans Gruber"

注:上述hello()直接调用的时候,this的指向就成了问题。在这种情况下,this往往被指向全局对象(GlobalObject),在浏览器上一般就是window对象。 
在ES5标准中,如果使用了strict mode,那么this会被设置为undefined:

function hello() { 
  "use strict"; 
  return "hello, " + this.username; 
} 
hello(); // error: cannot read property "username" of undefined

3.构造函数调用:

this指向:当前构造函数构建的对象

返回值:1.没有返回值,返回this

               2.return了一个基本数据类型(布尔值,字符串,数字,null,undefined),返回this

               3.返回了一个复杂数据类型(对象,数组等),返回该对象

代码1:
function Person() {
    this.age = 20;
    this.name = "张三";
    console.log(this);
}
//构造函数调用模式:
var p1 = new Person(); //打印出该实例 Person {age: 20, name: "张三"}
代码2;
function P2() {
    this.age = 18;
    return "abc";
}
var p2 = new P2();
console.log(p2); //P2 {age: 18}
代码3:
function P3() {
    this.age = 10;
    return {};
}
var p3 = new P3();
console.log(p3); //Object {}
console.log(p3.age);//undefined
代码4:
function P4() {
    this.age = 10;
    return [1, 3, 5];
}
var p4 = new P4();
console.log(p4);//[1, 3, 5]
console.log(p4.age);//undefined

4.上下文调用

        call和apply 是方法, 是所有函数都具有的方法。 Function.prototype

        只要函数调用call/apply 方法,那么该函数就会立即执行。

        this指向:   1.   传递一个null/undefined------------------->window

                            2.  传递一个数字、字符串、布尔值------->对应的基本包装类型的对象

                            3.  传递一个对象------------------------------->指向该对象

        返回值  :由return语句决定

对象的方法可以任意指派,而对象本身一直都是没有这方法的,注意是指派,通俗点就是,方法是借给另一个对象的调用去完成任务,原理上是方法执行时上下文对象改变了.

function f1(){
    console.log(this);
}
//上下文模式
f1.call(null);          //window
f1.call(undefined);     //window
f1.call(1);             //Number的实例
f1.call("abc");         //String的实例
f1.call(true);          //Boolean的实例
var s1="abc";           //代码内部创建了字符串所对应的String构造函数的实例
                        //        {0:"a",1:"b",2:"c",length:3}
                        //代码执行完毕之后,就会把这个实例给销毁
console.log(s1.length); //3
console.log(s1[0]);     //"a"