在《javaScript語言精粹》
這本書中,把 this
出現的場景分爲四類,簡單的說就是:javascript
有對象就指向調用對象 沒調用對象就指向全局對象 用new構造就指向新對象 經過 apply 或 call 或 bind 來改變 this 的所指。
函數調用模式中,this
爲window
;方法調用模式中,this
爲方法所屬的對象;構造器調用模式中,this
爲建立的新對象。html
js
中的this咱們要記住:this
永遠指向函數運行時所在的對象!而不是函數被建立時所在的對象。this
對象是在運行時基於函數的執行環境綁定的,在全局環境中,this
等於window
java
先來看個例子:jquery
<script> var fullname = "Trigkit4"; var person = { fullname : 'Jack', prop:{ fullname : 'Blizzard', getFullname : function () { return this.fullname; } } }; console.log(person.prop.getFullname());//Blizzard var test = person.prop.getFullname; console.log(test());//Trigkit4 </script>
當getFullname
被分配到test
變量時,上下文指的是全局對象(window)
。這是由於test
是被隱式設置爲全局對象的屬性。出於這個緣由,該函數返回window
的fullname
,因此在這裏 this
指的是window
, 因此返回的是第一個fullname
app
this
關鍵字一般在對象的 構造函數中使用,用來引用對象。函數
關鍵字this
:老是指向調用該方法的對象,如:ui
var iCar = new Object(); iCar.color = "red"; iCar.showColor = function(){ alert(this.color);//輸出"red" };
關鍵字this
用在對象的showColor()
方法中,在此環境,this
等於iCar
this
使用this
是由於在實例化對象時,老是不能肯定開發者會使用什麼樣的變量名。使用this
,便可在任意多個地方重用同一個函數。考慮下面的例子:code
function showColor(){ alert(this.color); } var oCar1 = new Object; oCar1.color = "red"; oCar1.showColor = showColor; var oCar2 = new Object; oCar2.color = "blue"; oCar2.showcolor = showcolor; oCar1.showColor();//輸出"red" oCar2.showColor();//輸出"blue"
這段代碼中,首先用this
定義函數showColor()
,而後建立兩個對象oCar1
和oCar2
,一個對象屬性被設置爲"red
",另外一個爲blue
;兩個對象都被賦予了屬性showColor
,指向原始的showColor()
函數,調用每一個showColor
的方法,oCar1
輸出red
,oCar2
輸出blue
。htm
引用對象屬性時,必須使用
this
關鍵字。
全部基於全局做用域的變量其實都是window
對象的屬性(property)。這意味着即便是在全局上下文中,this
變量也能指向一個對象。
對於 JScript
的客戶版本,若是在其餘全部對象的上下文以外使用 this
,則它指的是 window
對象。
例如:
<head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script type="text/javascript"> alert(this);//彈出 object window; </script> </head> <body> </body>
所謂構造函數,就是經過這個函數生成一個新對象(object)。這時,this
就指這個新對象。
<script type="text/javascript"> function test(){ this.x = 10; } var obj = new test(); alert(obj.x); //彈出 10; </script>
在看下面一個this
出如今全局環境中的例子:
<script type="text/javascript"> var name = "全局"; function getName(){ var name = "局部"; return this.name; }; alert(getName());//彈出 全局; </script>
函數getName()
所處的對象是window
對象,所以this
也必定在window
對象中。此時的this
指向window
對象,因此getName()
返回的this.name
實際上是window.name
,所以alert
出全局。
結論:不管this
身處何處,必定要找到函數運行時(或者說在何處被調用 了)的位置。
經過不一樣的調用語法,改變相同函數內部this
的值:
<script type="text/javascript"> var foo = { test:function(){ alert(this); } } foo.test();//object,由於test方法在調用時屬於foo對象 var baz = foo.test; baz();//window,由於baz()被調用時屬於global對象 </script>
看下面一個this
出如今局部環境中的例子
<script type="text/javascript"> var name = "全局"; var jubu={ name:"局部", getName:function(){ return this.name; } }; alert(jubu.getName()); </script>
其中this
身處的函數getName
不是在全局環境中,而是處在jubu環境中。不管this
身處何處,必定要找到函數運行時的位置。此時函數getName
運行時的位置:
alert(jubu.getName());
顯然,函數getName
所在的對象是jubu
,所以this
的安身之處定然在jubu
,即指向jubu
對象,則getName
返回的this.name
實際上是jubu.name
,所以alert
出來的是「局部」!
<script type="text/javascript"> function scoping () { console.log(this); return function () { console.log(this); }; } scoping()(); >>window >> window </script>
由於scoping
函數屬於window對象,天然做用域鏈中的函數也屬於window
對象。
能夠在對象的任何方法中使用this
來訪問該對象的屬性。這與用new
獲得的實例是不同的。
var obj = { foo: "test", bar: function () { console.log(this.foo); } }; obj.bar(); // "test"
沒法重寫this
,由於它是一個關鍵字。
function test () { var this = {}; // Uncaught SyntaxError: Unexpected token this }
apply
和 call
調用以及 bind
綁定都是指向綁定的對象,
<script type="text/javascript"> var bar = { value: 'huang', ages: 10 }; function foo(){ console.log(this); } console.log(foo());//window,函數沒有所屬對象:指向全局對象 console.log(foo.apply(bar));//即bar.foo(),this指向了bar,因此能讀取該對象的全部屬性 console.log(foo.call(bar));//ages: 10 value: "huang" __proto__: Object var newFoo = foo.bind(bar); console.log(newFoo());//Object </script>
$()
生成的是什麼呢?實際上$()=jquery()
,那麼也就是說返回的是一個jquery
的對象。$(this)
是jquery
對象,能調用jquery
的方法,例如click()
, keyup()
。
$(function () { $('button').click(function () { alert(this);//this 表示原生的DOM //$(this)表示當前對象,這裏指的是button }) });
在許多狀況下JQuery
的this
都指向HTML
元素節點。
結論:this
,表示當前的上下文對象是一個html DOM
對象,能夠調用html
對象所擁有的屬性,方法。$(this)
,表明的上下文對象是一個jquery
的上下文對象,能夠調用jquery
的方法和屬性值。