写在面向对象之前

This语法

全局的语境中

在全局中(任何函数之外),无论全局对象是否在严格模式下,this指代全局对象。

在浏览器中, window 对象也是全局对象:
console.log(this === window); // true   
a = 37;
console.log(window.a); // 37    
this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"

在函数中

在函数内部,this的值取决于函数被调用的方式。

1.简单的调用

下面的代码不是严格的模式,并且由于this不是通过调用设置的,所以这个默认为全局对象。

function f1(){
return this;
}
在浏览器中:
f1() === window;  
在浏览器中,全局对象是window
在Node中:
f1() === global;

如果this未被定义,那么他的默认值是defined
如果要把this的值从上一个传到另一个,就要用call()或者apply()方法。

一个对象可以作为call和apply的第一个参数,并且this会被绑定到这个对象。

var obj = {a: ‘Custom’};

这个属性是在global对象定义的。

var a = 'Global';
function whatsThis(arg) {   
return this.a;  // this的值取决于函数的调用方式 }
whatsThis();    //'Global'
whatsThis.call(obj);  //'Custom'
whatsThis.apply(obj); // 'Custom'

当在函数使用this关键字时,他的值被绑定到调用中的特定对象,而全部的函数继承Function.prototypecall或者apply方法。

function add(c, d) {       
return this.a + this.b + c + d; }   
var o = {a: 1, b: 3};
第一个参数是作为‘this’使用的对象
后续参数作为参数传递给函数调用
add.call(o, 5, 7); 
第一个参数也是作为‘this’使用的对象
第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o,[10, 20]); //34

使用callapply时要注意,如果传递的this不是一个对象,将会在内部使用ToObject操作把他转换为对象。所以,如果传递的原始值7 或者'foo',他将使用相关的构造函数转换为对象,原始值7被转换为一个对象就像new Number(7)一样,而且字符串foo被转换为对象就像new String('foo')一样,举个栗子:

function bar() { 
    console.log(Object.prototype.toString.call(this));
}
bar.call(7); //[object Number]
bar.call('foo')//[object String]

2.在对象中

在函数被作为对象中的方法时,this是调用该函数的对象。
在下面的例子中,当o.f()被调用时,在function里面this被绑定到o对象。

var o = { 
    prop: 37,   
    f: function() {
    return this.prop; 
    } };
console.log(o.f()); // logs 37

请注意,此行为完全不受如何或在何处定义函数的影响。 在前面的例子中,我们在o的定义过程中将函数内联定义为f成员。 但是,我们可以先轻松定义函数,然后将其附加到o.f. 这样做会导致相同的行为。
所以,只有函数是从o的f成员调用才有意义。

原型链中的this

相同的概念在定义在原型链中的方法也是一致的。如果该方法存在于一个对象的原型链上,那么this指向的是调用这个方法的对象,就好像该方法本来就存在于这个对象上。

var o = {   f : function(){   
return this.a + this.b;   
} }; 
var p = Object.create(o);
p.a = 1; 
p.b = 4;
console.log(p.f()); // 5

在这个例子中,对象p没有属于它自己的f属性,它的f属性继承自它的原型。但是这对于最终在o中找到f属性的查找过程来说没有关系;查找过程首先从p.f的引用开始,所以函数中的this指向p。也就是说,因为f是作为p的方法调用的,所以它的this指向了p。这是 JavaScript 的原型继承中的一个有趣的特性。

3.在构造函数中

当函数被用作构造函数时(带着new关键字),this会被作为构造函数绑定在新对象中。

构造函数这样工作:

function MyConstructor(){    
    // 函数实体写在这里   }
根据需要在this上创建属性,然后赋值给它们,比如:    
this.fum = "nom";     
等等...   
如果函数具有返回对象的return语句,则该对象将是 new 表达式的结果。      
否则,表达式的结果是当前绑定到 this 的对象。 
(即通常看到的常见情况)。  

function C(){   
    this.a = 37; }
var o = new C();
console.log(o.a); // logs 37

function C2(){   
    this.a = 37;   
    return {a:38}; }

在刚刚的例子中(C2),因为在调用构造函数的过程中,手动的设置了返回对象,与this绑定的默认对象被丢弃了。(这基本上使得语句 “this.a = 37;”成了“僵尸”代码,实际上并不是真正的“僵尸”,这条语句执行了,但是对于外部没有任何影响,因此完全可以忽略它)。

this还有其他的用法,学到后面再更新..

全文参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this