this
在全局執行上下文(函數以外),this引用的是全局對象.
javascript
console.log(this.document === document); // true // In web browsers, the window object is also the global object: console.log(this === window); // true this.a = 37; console.log(window.a); // 37
在函數裏面,this這個值,得看怎麼來調用這個函數
java
function f1(){ return this; } f1() === window; // global object
function f2(){ "use strict"; // see strict mode return this; } f2() === undefined;
當一個函數做爲一個對象的方法去調用,this指向的是對象自己.
web
下面的例子中,當 o.f()被調用,函數裏面的this指向的是 o對象.
express
var o = { prop: 37, f: function() { return this.prop; } }; console.log(o.f()); // logs 37
假如 o 對象只申明瞭一個屬性,其f方法在開始聲明時尚未被定義,而後經過o.f直接被賦值爲其餘方法,其最後的效果也是同樣的,只是定義的先後問題,this依然指向的是o這個對象:瀏覽器
var o = {prop: 37}; function independent() { return this.prop; } o.f = independent; console.log(o.f()); // logs 37
這個例子說明的是f函數的調用,是做爲o的成員方法來執行.微信
咱們繼續來看,若是咱們給o設定另一個成員屬性b賦予爲一個對象,看下面這個例子,這時候,this該指向的是誰呢? 前面已經說過,this指向的是對象自己,因此o.b做爲一個對象,一樣這個對象的this指向的是他本身o.b.app
o.b = {g: independent, prop: 42}; console.log(o.b.g()); // logs 42
一樣的概念也使用對象原型鏈中
函數
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沒有本身的屬性.它繼承了o的屬性.因此這時候經過p來調用f方法,this指向的是p,這是對象原型模式.這裏就是javascript中的原型繼承模式.ui
再次,用相同的概念也適用於getter和setter.函數使用getter或者setter來綁定到對象的屬性. this
function modulus(){ return Math.sqrt(this.re * this.re + this.im * this.im); } var o = { re: 1, im: -1, get phase(){ return Math.atan2(this.im, this.re); } }; Object.defineProperty(o, 'modulus', { get: modulus, enumerable:true, configurable:true}); console.log(o.phase, o.modulus); // logs -0.78 1.4142
.當一個函數做爲一個構造函數使用(同構new來構造).this這時候指向的是函數構造出來的對象.
提示: 雖然默認構造函數返回對象引用,它也能夠返回其餘對象 .
/* * Constructors work like this: * * function MyConstructor(){ * // Actual function body code goes here. * // Create properties on |this| as * // desired by assigning to them. E.g., * this.fum = "nom"; * // et cetera... * * // If the function has a return statement that * // returns an object, that object will be the * // result of the |new| expression. Otherwise, * // the result of the expression is the object * // currently bound to |this| * // (i.e., the common case most usually seen). * } */ function C(){ this.a = 37; } var o = new C(); console.log(o.a); // logs 37 function C2(){ this.a = 37; return {a:38}; } o = new C2(); console.log(o.a); // logs 38
在最後的例子中(C2),由於一個對象在構造函數期間返回,這個新對象就會被丟棄.("this.a=37"; 其實沒什麼做用的代碼.可是他也不是徹底是死碼,由於他被執行了.可是沒有影響到外面的代碼執行.)
call
和 apply
一個函數在內部使用this,經過使用call或者apply方法將它的值綁定到一個特殊的對象.全部方法繼承Function.prototype.
function add(c, d){ return this.a + this.b + c + d; } var o = {a:1, b:3}; // The first parameter is the object to use as // 'this', subsequent parameters are passed as // arguments in the function call add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 // The first parameter is the object to use as // 'this', the second is an array whose // members are used as the arguments in the function call add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
咱們來看下下面的這個列子.bar.call(7)這一行代碼,將第一個參數爲一個數值,則這時候的bar方法裏面的this是指向Number.到這裏,你能夠試試執行另外的一行代碼 new Number(10).toString(),看看效果.
function bar() { console.log(Object.prototype.toString.call(this)); } bar.call(7); // [object Number]
bind方法
ECMAScript 5 介紹了 Function.prototype.bind
. bind是建立了一個新函數而不是修改一個函數.新函數的行爲和原來函數的行爲同樣,但他的接收者是咱們給定的對象,而原有函數的接收者保持不變.
function f(){ return this.a; } var g = f.bind({a:"azerty"}); console.log(g()); // azerty var o = {a:37, f:f, g:g}; console.log(o.f(), o.g()); // 37, azerty
做爲DOM事件處理
當一個函數用在事件處理上.他的this將是指向這個元素的自己事件(使用addEventListener添加監聽器事件中,有些瀏覽器不遵照公約,有本身的一套作法.)
// When called as a listener, turns the related element blue function bluify(e){ // Always true console.log(this === e.currentTarget); // true when currentTarget and target are the same object console.log(this === e.target); this.style.backgroundColor = '#A5D9F3'; } // Get a list of every element in the document var elements = document.getElementsByTagName('*'); // Add bluify as a click listener so when the // element is clicked on, it turns blue for(var i=0 ; i<elements.length ; i++){ elements[i].addEventListener('click', bluify, false); }
內聯事件處理
當代碼在元素上進行調用處理,this指向的是這個DOM元素.
<button onclick="alert(this.tagName.toLowerCase());"> Show this </button>
上面顯示的是這個按鈕. 記住只有這種方式,返回的是這個元素.
<button onclick="alert((function(){return this}()));"> Show inner this </button>
在這個例子中,內部函數this沒有被設置,所以它返回的全局對象window.
本文屬於吳統威的博客,微信公衆號:bianchengderen 的原創文章,轉載時請註明出處及相應連接:http://www.wutongwei.com/front/infor_showone.tweb?id=156 ,歡迎你們傳播與分享.