JS中call(),apply(),bind()函數的區別與用法詳解
call()
介紹
通過提供一個新的this值給當前調用的函數/方法,從而改變this指向。
語法
fn.call(this.Arg, arg1, arg2,...)
thisArg:當前調用函數this指向的對象
arg1, arg2:傳遞的其他參數(直接傳給形參可不寫)
特點
- 可以直接調用函數—
fn.call()
- 可以改變被調用函數的this指向為指定的—
fn.call(this.Arg)
返回值
使用調用者提供的值和參數調用該函數的返回值,也就是函數的返回值。若該方法沒有返回值,則返回undefined
。
使用(主要應用)
通過使用call()來實現繼承
// 借用父構造函數繼承屬性 // 父構造函數 function Father(name, age) { this.uname = name this.age = age } // 子構造函數 function Son(name, age) { Father.call(this, name, age) } var son = new Son('小明', 10) console.log(son); // Son {uname: '小明', age: 10}
apply()
介紹
apply-應用、運用的意思。
apply()-調用一個具有給定值的函數,以及以一個數組(或一個類數組對象)的形式提供的參數this
,簡單理解為調用函數的,fang'shi但是它可以改變this指向。
語法
fn.apply(this.Arg, [argsArray])
thisArg:在fn函數運行時指定的this值,當不需要改變this指向時這裡可以填null 。
argsArray:傳遞的值,必須包含在數組裡面。
特點
- 也是調用函數—
fn.apply()
- 可以改變函數內部的this指向—
fn.apply(this)
但是它的參數必須是數組(偽數組)
返回值
apply()的返回值就是函數的返回值,因為它就是調用函數。
使用調用者提供的值和參數調用該函數的返回值。若該方法沒有返回值,則返回undefined
。
使用
var a = { name: '小紅' } function fn(arr) { console.log(this); // {name: '小紅'} console.log(arr); // blackpink 傳字符串就輸出字符串傳數字就輸出數字 } fn.apply(a, ['blackpink']) // fn.apply() // this->window arr->undefined
典型應用: 借助於數學內置對象求值。
var arr = [1, 66, 3, 99, 4] // var max = Math.max.apply(null, arr) // 雖然這裡的this指向不需要改變填null沒有錯 var max = Math.max.apply(Math, arr) // 但是這裡最好是讓this指向函數的調用者是最合適的 var min = Math.min.apply(Math, arr) console.log(max); // 99 console.log(min); // 1
bind()
介紹
bind:綁定、捆綁
bind():不會調用函數,但是也能改變函數內部的this指向
語法
fn.bind(thusArg, arg1, arg2, ...)
thisArg:在fn函數運行時指定的this值
arg1, arg2:傳遞的其他參數
特點
- 不會調用原來的函數,不會立即調用;
- 可以改變原來函數內部的this指向;
- 返回的是原函數改變this之後產生的新函數;
返回值
- 返回由指定的this值和初始化參數改造的原函數拷貝。
使用
var c = { name: '大華' } function fn() { console.log(this); // {name: '大華'} console.log(a + b); // 3 } // fn.bind(c) // 這裡不會有輸出值 var f = fn.bind(c, 1, 2) f() // 拷貝函數所以輸出值用函數調用
典型應用:
如果有的函數我們不需要立即調用,但是又想改變這個函數內部this指向,此時用bind(),eg:點擊發送驗證碼60秒後才能二次點擊
<button>按鈕</button> <button>按鈕</button> <button>按鈕</button>
var btns = document.querySelectorAll('button') for (var i = 0; i < btns.length; i++) { btns[i].onclick = function() { this.disabled = true // 這個this指向的是調用者btn setTimeout(function() { // this.disabled = false; // 隻用這一個不加bind的話會不管用,因為定時器裡面的this指向的是window this.disabled = false // 此時這裡的this指向的是當前點擊的那個btn }.bind(this), 3000) // 這個this指向的是btn這個對象 } }
call(),apply(),bind()的區別
三者相同點
- 都可以改變函數內部的this指向
不同點
call
和apply
會調用函數,並且改變函數內部this指向;call
和apply
的傳參不一樣,call
傳參aru1, aru2…形式,apply
必須為數組形式 [arg] ;bind
不會直接調用函數,但是可以改變函數內部this指向;
應用場景不同:
call
經常做繼承;apply
經常跟數組有關系,比如借助於數學對象實現數組最大最小值;bind
不調用函數,但是還想改變this指向,比如改變定時器內部this指向;
以上既是JS中call(),apply(),bind()函數的區別與使用方法,更多關於這3個函數的使用方法請查看下面的相關鏈接
推薦閱讀:
- 一文瞭解JavaScript中call/apply/bind的使用
- 使用JS簡單實現apply、call和bind方法的實例代碼
- Javascript中函數分類&this指向的實例詳解
- JavaScript函數this指向問題詳解
- 一文搞懂JavaScript中的this綁定規則