在JavaScript中的this不是固定不變的,隨著他的環境而改變
為什么使用this:
看下面這個代碼:
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
為什么物件自己的方法想使用自己物件的屬性,會出現報錯資訊?
從存盤結構、函式運行的原理進行解釋;
當打開瀏覽器的時候,記憶體會創建一個window變數全域作用物件,在這個代碼中,只存在一個lilei這個全域作用物件,包含很多的成員變數,而每個函式都有一個scopes屬性,它緊密的跟函式的外層作用域相結合,一個函式能用哪些變數,取決于這個鏈上都有哪些變數,
js當中只用兩級作用域,一級是全域,一級是函式,lilei物件不是函式,如果存資料,也進不了scopes,所以intr函式的scopes指向外面更大的作用域
任何函式呼叫時,先創建臨時的函式作用域,然后將自己臨時的作用域與window全域作用域形成作用域鏈,intr自己沒有區域變數(一種是var出來的,另一種是形參),sname、sage不滿足上述兩種要求,所以這個函式作用域是空的,物件不是作用域,所以物件的成員屬性無法進入作用域鏈被函式訪問,
結論:物件自己的方法不能輕易訪問自己的成員,物件不是作用域,成員不會自己進入作用域,
解決:給sname、sage前加lilei.
缺點:lilei僅僅是一個變數名,變數名可以發生變化的,而呼叫的lilei也被迫跟著變化,這就是緊耦合,而我們需要松耦合,就是外面怎么變化,里面不發生變化,實作方法,將lilei.替換為關鍵字this.,
this指的是正在呼叫函式的.前的物件
所以被呼叫的lilei可以改為this,在運行時this會被換為lilei,在呼叫的時候,.前是lilei,this指誰,跟存在的地方無關,看的是.前是誰,
這樣寫,以后物件名lilei改為ll時,里面的this不用改,依然是指向.前的呼叫的ll,
什么是: 在函式呼叫時,自動指向.前的物件的關鍵詞
為什么: 避免在物件的方法中寫死物件名,形成緊耦合,
何時: 只要物件自己的方法,想訪問自己的成員時,都要加this.
1. this和定義在哪兒無關,只和呼叫時.前的物件有關
2. 全域函式呼叫,沒有., this默認指window
this的作用:
1、在方法中呼叫:則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
2、單獨使用this,this指向全域物件
var x = this; //this指向[object Window]
3、函式中使用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" }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/53614.html
標籤:JavaScript
