在JavaScript中的this不是固定不變的,隨着他的環境而改變瀏覽器
爲何使用this:app
看下面這個代碼:函數
var lilei={ sname:"Li Lei", sage:11, intr:function(){ document.write(`<h1> I am ${sname},I am ${sage}</h1>`) } } lilei.intr(); //會報錯 sname is not defined
爲何對象本身的方法想使用本身對象的屬性,會出現報錯信息?this
從存儲結構、函數運行的原理進行解釋;spa
當打開瀏覽器的時候,內存會建立一個window變量全局做用對象,在這個代碼中,只存在一個lilei這個全局做用對象,包含不少的成員變量,而每一個函數都有一個scopes屬性,它緊密的跟函數的外層做用域相結合,一個函數能用哪些變量,取決於這個鏈上都有哪些變量,code
js當中只用兩級做用域,一級是全局,一級是函數,lilei對象不是函數,若是存數據,也進不了scopes,因此intr函數的scopes指向外面更大的做用域對象
任何函數調用時,先建立臨時的函數做用域,而後將本身臨時的做用域與window全局做用域造成做用域鏈,intr本身沒有局部變量(一種是var出來的,另外一種是形參),sname、sage不知足上述兩種要求,因此這個函數做用域是空的,對象不是做用域,因此對象的成員屬性沒法進入做用域鏈被函數訪問,blog
結論:對象本身的方法不能輕易訪問本身的成員,對象不是做用域,成員不會本身進入做用域,事件
解決:給sname、sage前加lilei.ip
缺點:lilei僅僅是一個變量名,變量名能夠發生變化的,而調用的lilei也被迫跟着變化,這就是緊耦合,而咱們須要鬆耦合,就是外面怎麼變化,裏面不發生變化,實現方法,將lilei.替換爲關鍵字this.,
this指的是正在調用函數的.前的對象
因此被調用的lilei能夠改成this,在運行時this會被換爲lilei,在調用的時候,.前是lilei,this指誰,跟存在的地方無關,看的是.前是誰。
這樣寫,之後對象名lilei改成ll時,裏面的this不用改,依然是指向.前的調用的ll。
什麼是: 在函數調用時,自動指向.前的對象的關鍵詞
爲何: 避免在對象的方法中寫死對象名,造成緊耦合。
什麼時候: 只要對象本身的方法,想訪問本身的成員時,都要加this.
1. this和定義在哪兒無關,只和調用時.前的對象有關
2. 全局函數調用,沒有., this默認指window
this的做用:
一、在方法中調用:則this表示該方法所屬的對象或全局對象
在外包裹一個指定的對象時,方法中的this指向包裹他的對象,若是有不少層對象包裹,則this指向最深層調用他的第一個對象,
var name = 'windowdada'; var obj = { name: 'objdada', objB: { name: 'objBdada', bFun: function(){ console.log(this.name); } } }; var test = obj.objB.bFun(); //輸出結果爲objBdada ,()左邊是bFun引用,它指向objB這個對象,因此打印出objBdada var test2 = obj.objB.bFun; test2(); //輸出結果爲windowdada, ()的左邊爲test2,它不是某個對象的引用,因此是全局對象 var test3 = obj.objB; var test4 = test3.bFun; test4(); //同上
var name = 'windowDada'; var obj = { name: 'dada', foo: function () { console.log(this.name); } }; var foo = obj.foo; // 寫法一 obj.foo()// dada // 寫法二 foo() //windowDada
二、單獨使用this,this指向全局對象
var x = this; //this指向[object Window]
三、函數中使用this(非嚴格模式)
根據函數所屬默認綁到this上,那麼在瀏覽器中,window就是該全局對象[object window]
則this指的是全局對象[object Window]
函數中使用this(嚴格模式)
嚴格模式下this 函數沒有綁定到this上,此時的this是undefined
在事件中的this,this指向接收事件的HTML元素,對該元素進行操做
對象中綁定的this,this是屬於一個對象,而對象是函數的全部者
call的用法:
call方法用來代替另外一個對象調用一個方法,該方法能夠將一個函數對象的上下文改變爲由this obj指定的新對象。
call方法的參數,
1.若是是不傳,或是null,undefined的狀況下,函數中的this指向就是指window對象,
2.若是傳遞的是另外一個函數的函數名,函數中的this指向就是這個函數的引用,
3.若是參數傳遞的是基本類型數據時,函數中的this指向就是其對應的 包裝對象了,
4.若是參數傳遞的是一個對象時,函數中的this就指向這個對象。
var da = { name: "da", sayHello: function (age) { console.log("hello, i am ", this.name + " " + age + " years old"); } }; var jeskson = { name: "jeskson", }; da.sayHello(12); //hello, i am da 12 years old da.sayHello.call(jeskson,13); // hello, i am jeskson 13 years old
顯示函數綁定:
call(thisObj,arg1,arg2,arg...)
var person1 = { fullName: function() { return this.firstName + " " + this.lastName; } } var person2 = { firstName:"John", lastName: "Doe", } var x = person1.fullName.call(person2); document.getElementById("demo").innerHTML = x;
apply的用法:
apply(thisObj,argArray) var person={ fullName:function(){ return this.firstName+""+this.lastName; }} var person1={ firstName:"Bill", lastName:"Gates", } person.fullName.apply(person1); //返回"Bill Gates" }