您好,登錄后才能下訂單哦!
本篇內容主要講解“JavaScript this綁定與this指向問題如何解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript this綁定與this指向問題如何解決”吧!
其實 this 就是一個指針,它指示的就是當前的一個執行環境,可以用來對當前執行環境進行一些操作。
MDN 解釋:在絕大多數情況下,函數的調用方式決定了 this 的值(運行時綁定)。this 不能在執行期間被賦值,并且在每次函數被調用時 this 的值也可能會不同。ES5 引入了 bind 方法來設置函數的 this 值,而不用考慮函數如何被調用的。ES2015 引入了箭頭函數,箭頭函數不提供自身的 this 綁定(this 的值將保持為閉合詞法上下文的值)。
每個函數的 this 是在調用時被綁定的,完全取決于函數的調用位置。我們找到函數的調用位置,然后運用以下四種綁定規則來判斷函數的 this 指向。
1、默認綁定
函數的 this 會默認綁定到全局對象 window 上,如果在嚴格模式中,this 綁定到 undefined。
function foo (){ console.log(this.a) } let a = 1 foo() // 1
2、隱式綁定
調用位置是否有上下文對象,或者被某個對象擁有或包含。
function foo(){ console.log(this.a) } let obj = { a: 2, foo:foo } let a = 1 obj.foo(); // 2 function foo(){ console.log(this.a) } let obj1 = { a: 2, foo: foo } let obj2 = { a: 3, obj1: obj1 } let a = 1 obj2.obj1.foo(); // 2
3、顯式綁定
直接改變 this 指向,綁定到另一個執行環境
function foo(){ console.log(this.a) } let obj = { a: 1 } foo.call(obj)
4、new 綁定
new 出來的函數 this 綁定的是新創建的對象
function Foo(a){ this.a = a } let bar = new Foo(2) console.log(bar.a) // 2
默認綁定的優先級是最低的
new 綁定 > 顯式綁定 > 隱式綁定 > 默認綁定
1、顯示綁定 VS 隱式綁定
function foo(){ console.log(this.a) } let obj1 = { a: 1, foo: foo } let obj2 = { a: 2 } console.log(obj1.foo()) // 1 obj1.foo.call(obj2) // 2
通過以上代碼我們可以看到 顯式綁定 的優先級高于 隱式綁定
2、顯示綁定 VS new 綁定
function foo(a){ this.a = a } let obj1 = { foo } let bar = foo.bind(obj1) bar(2) console.log(obj1.a) // 2 let bar2 = new bar(3) console.log(obj1.a) // 2 console.log(bar2.a) // 3
new 修改了顯示綁定 調用 bar 中的 this,所以 new 綁定的優先級高于顯式綁定
第一準則:this 永遠指向函數運行時所在的對象,而不是函數被創建時所在的對象。(不包含箭頭函數)
第二準則:無論是否在嚴格模式下,在全局執行環境中(在任何函數體外部)this 都指向全局對象。
函數是否在 new 中調用,如果是的話 this 綁定的是新創建的對象;
函數是否通過 call、apply、bind 的方式調用,如果是的話 this 綁定的是指定的對象;
函數是否在某個上下文中被調用,如果是的話 this 綁定的是函數調用的上下文;
除此之外 this 綁定的就是全局對象 在嚴格模式下綁定的是 undefined。
箭頭函數沒有自己的 this 指針(需要從執行上下文來進行判斷)
變量保存 this:將 this 臨時保存下來
call():使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。
bind():會有一個返回值,返回值是一個擁有第一個函數作用域的新的函數體
apply():調用一個具有給定 this 值的函數,以及以一個數組(或一個類數組對象)的形式提供的參數。
var _this = window; var obj = { name:"張三", show:function(){ console.log(this) //obj console.log(_this) // window } } obj.show()
call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。
函數名稱.bind(參數1,參數2,a,b,c.....)
參數1:當前函數的作用域
參數2:需要傳遞的參數,參數是一個一個傳
function fn(a,b){ console.log(this,a,b) } document.onclick = functioin(){ fn.call(document,1,2) }
可以使用 call 來實現繼承:寫一個方法,然后讓另外一個新的對象來繼承它(而不是在新對象中再寫一次這個方法)。
function Product(name, price) { this.name = name; this.price = price; } function Food(name, price) { Product.call(this, name, price); this.category = 'food'; } function Toy(name, price) { Product.call(this, name, price); this.category = 'toy'; } var cheese = new Food('feta', 5); var fun = new Toy('robot', 40);
bind 創建一個新的函數,在 bind() 被調用時,這個新函數的 this 被指定為 bind() 的第一個參數,而其余參數將作為新函數的參數,供調用時使用。
特性就是會有一個返回值,返回值是一個擁有第一個函數作用域的新的函數體
函數名稱.bind(參數1,參數2.....)() // 必須調用一下
參數1:當前函數的作用域
參數2:需要傳遞的參數
var obj = { name:"張三", show:function(val){ console.log(this) //obj 沒有修改前 console.log(this,1) // document 1 修改后 } } obj.show().bind(document,1)()
MDN:ECMAScript 5 引入了 Function.prototype.bind()。調用 f.bind(someObject) 會創建一個與 f 具有相同函數體和作用域的函數,但是在這個新函數中,this 將永久地被綁定到了 bind 的第一個參數,無論這個函數是如何被調用的。
apply() 方法調用一個具有給定 this 值的函數,以及以一個數組(或一個類數組對象)的形式提供的參數。
函數名稱.bind(參數1,[參數2,a,b,c.....])
參數1:當前函數的作用域
參數2:需要傳遞的參數 數組
function fn(a,b,c){ console.log(this,a,b,c) } document.onclick = functioin(){ fn.apply(document,[1,2,3]) }
不同點:
bind 會有一個返回值,返回值是函數體,因此需要加上 () 才能調用
call,apply 是沒有返回值的,當改變函數 this 指向的時候,函數就會執行,不需要加 () 調用
call 傳遞參數的時候是一個一個傳遞的
apply 是傳遞一個數組或者類數組對象的參數
到此,相信大家對“JavaScript this綁定與this指向問題如何解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。