文章目錄
- 1. 默認系結規則
- 2. 隱式系結規則
- 3. 顯示系結:call,apply,bind
- 4. new 系結
我們在寫前端頁面的時候,撰寫JavaScript代碼的時候經常會用到this關鍵字,比如系結事件等等,但是JavaScript中的this指向問題一直都是比較讓人頭疼的問題,特別是對于初學者來講,本來認為代碼沒有什么問題,結果運行出來不盡人意,而且還要花大量時間來除錯找到問題所在,以下內容是根據自己所理解進行分享,有什么不對的地方希望大家指出,并一起討論,一起進步,
首先我們要明白,this 是在代碼執行程序中才會對其進行賦值,這也是 this 指向復雜的原因之一
1. 默認系結規則
在 JavaScript 中 this 默認系結全域變數,例如在全域變數中列印 this 就會顯示 window 物件
console.log(this) // window 物件
console.log(this === window) // true 這也表示在全域范圍內this 默認指向 window 物件
這一點很好理解,不用多講
2. 隱式系結規則
總的來講,就是誰呼叫就指向誰
function abc(){
console.log(this); // window
}
abc();
// 這里列印出的還是 window 物件,因為 abc() 等同于 window.abc();
// 還有就是當函式獨立呼叫的時候,就是不借助其他自身呼叫時,this 指向的也是 window
這也很好理解,再來換一個例子
let a = 0;
let obj = {
a:2,
fn:function(){
console.log(this); // obj
function test(){
console.log(this) // ?
}
test();
}
}
obj.fn();
// 通過物件的屬性的方式來呼叫方法時,this 就會指向物件,
但是在物件中函式中再定義一個函式時,這個時候 this 指向的會是什么呢?
回到第一點所講過的,當函式不借助其它,通過自己來呼叫時,this 默認指向的是 window ,所以在上面的那個例子 第二個 this 指向的就是 window
同理,立即執行的函式中的 this 也為 window
(function(){
console.log(this) // window
})()
再來看閉包中的 this
let obj = {
fn:function(){
return function(){
console.log(this)
}
}
}
obj.fn()() // window
可能這里就會有疑問了,這里是用了 obj 中的屬性來進行呼叫的,但是為什么還是輸出的是 window 物件呢,因為 obj.fn() 先執行時,回傳的是 test 方法的參考(也可以理解為指標),通過這個參考呼叫 test 方法,就等同于 test() 這又回到了第一點中的函式獨立呼叫時,this 默認指向的是 window
再來個例子(隱式丟失)
var a = 0;
function foo(){
console.log(this);
}
let obj = {
a:2,
foo:foo
}
obj.foo(); // 這里沒有疑問,列印的 obj
// 隱式丟失
let fn = obj.foo;
fn(); // 這里列印出來的為 window
這個例子有一個專有名詞叫做隱式丟失,我個人理解和上一個例子中的閉包中的 this 很相像,通過函式的參考來呼叫函式,就會丟失物件,的參考,所以叫做隱式丟失,這里還能理解為函式的獨立呼叫,也是指向的 window,
函式傳參之間的 this 指向(引數賦值)
let a = 0;
function foo(){
console.log(this) // window
}
function bar(fn){
fn();
}
let obj = {
a:2,
foo:foo,
}
bar(obj.foo)
這個例子中,通過物件中的屬性來進行傳遞引數,最終列印出來的window物件,這里可以理解函式在傳遞引數的時候只是傳遞了函式的參考,也就是說只是傳遞了函式的指標,并沒有傳遞這個函式是通過哪個物件來得到了,所以最終列印出來的也是 window 物件
3. 顯示系結:call,apply,bind
通過這三個方法對函式中的 this 進行改變,在 javascript 面向物件中起著很關鍵的作用,知識比較多,這里就不細講了,可以直接看 API
4. new 系結
只有是在 建構式時,才會用到 new 系結,是將實體化的物件系結到 this
function Person(){
age:18;
// return 1;
// return {};
}
let person = new Person();
console.log(this)
這里需要注意的是回傳值的問題,當回傳值不是一個物件的時候,通過new來賦值的就是實體化物件本身,但是如果手動添加的回傳值是一個物件,那么這個物件就會賦值給 person (實際開發程序中極少用到)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/289609.html
標籤:其他
上一篇:JQuery獲取元素
下一篇:學習JavaScript的第一天
