this是函數運行時自動生成的一個內部對象,只能在函數內部使用,但總指向調用它的對象。
通過以下幾個例子加深對this的理解。
(1)作為函數調用
var name = 'Jenny'; function person() { return this.name; } console.log(person()); //Jenny
上面這個例子在全局作用域中調用person(),此時的調用對象為window,因此this指向window,在window中定義了name變量,因此this.name相當於window.name,為Jenny。
再看下面一個例子:
function a() { function b() { function c() { console.log(this); } c(); } b(); } a(); // window
這個例子中,也同為函數調用,因此this指向window。
(2)作為對象的方法調用
var name = 'Jenny'; var obj = { name: 'Danny', person: function() { return this.name; } }; console.log(obj.person()); //Danny
在這個例子中,person()函數在obj對象中定義,調用時是作為obj對象的方法進行調用,因此此時的this指向obj,obj里面定義了name屬性,值為Danny,因此this.name = "Danny"。
(3)作為構造函數調用
作為構造函數調用和普通函數調用的區別是,構造函數使用new關鍵字創建一個實例,此時this指向實例對象。
function person() { return new person.prototype.init(); } person.prototype = { init: function() { return this.name; }, name: 'Brain' }; console.log(person().name); //undefined
這是一個比較復雜的例子,涉及到了原型。
首先,創建構造函數person,為函數重新定義原型,在原型上定義了兩個方法init和name,其中init返回this.name。
調用person函數的name屬性,發現返回的是undefined,為什么不是Brain呢?
我們看,調用person,返回person.prototype.init()的一個實例,假設返回的這個實例名為a,那么此時的this指向的就是a,a作為person.prototype.init()的一個實例,那么所有定義在person.prototype.init()中的方法等都可以被a調用,但是name屬性定義在person的原型中,而非init函數中,因此返回undefined。
(4)apply和call
使用apply()和call()可以改變調用函數的對象,第一個參數為改變后調用這個函數的對象,其中apply()的第二個參數為一個數組,call的第二個參數為每個參數。
function person() { return this.name; } var obj = { name: 'Jenny', age: 18 }; console.log(person.apply(obj)); //Jenny
使用apply函數改變了調用person的對象,是在obj對象下面調用person,不再是在window對象下調用了,因此this指向obj,this.name = "Jenny";
參考:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
http://www.cnblogs.com/aaronjs/p/3278578.html