咱們在看一些插件的時候,常常會用到這 3 個函數,那麼他們具體的用途是什麼呢?區別又是什麼呢?咱們先看看下面一段代碼:javascript
var name = '小白' var obj = { name: '小明', getName: function () { console.log(this, this.name) return this.name } } var getName = obj.getName obj.getName() // obj, 小明 getName() // window,小白
是否是很神奇,同一個函數,執行的結果不同,這裏涉及到一個this
的指向問題。前端
this
指向js
中一個普通函數this
的指向與其自己無關,只與調用該函數的對象有關。根據這個規則,咱們回到上面的問題,obj.getName
調用getName
函數的對象是obj
,因此this
指向了obj
對象,那麼獲得的obj.name
爲小明;而getName()
是直接調用的函數,其實是window.geName()
是window
對象在調用函數,this
則指向window
對象。(use strict 嚴格模式下,全局 this 是 undefined,而不是window
)。
關於this
的指向這裏不作具體講解,畢竟這是個複雜的問題,後面再分狀況講解,畢竟這也是一個高頻面試題。java
這 3 個函數的做用是,改變一個函數在執行時this
的指向。咱們來改造上面的代碼。面試
var name = '小白'; var obj = { name: '小明', getName: function () { console.log(this, this.name) return this.name } }; var obj1 = {name: '小花'} var getName = obj.getName; getName(); // window,小白 obj.getName(); // obj, 小明 getName.apply(obj); // obj,小明 getName.call(obj1); // obj1,小花 getName.bind(obj)(); // obj,小明
能夠看到,當咱們改用apply
去調用函數時,無論其所在的做用域,咱們的this
指向bind,apply,call
函數接受的第一個參數。數組
相同點:三個函數都是爲了改變被調用函數的this
指向,都指向接受的第一個參數。
不一樣點:app
apply
和call
都是直接調用函數,而bind
則是先將函數暫存起來,須要再單獨調用一次。apply
和call
第一個參數同樣,都是要綁定給 this 的值,若是這個值爲null
或者undefined
,則爲window
對象。他們的區別在第二個參數上:當函數須要傳遞多個變量時, apply
能夠接受一個數組做爲參數輸入, call
則是接受一系列的單獨變量。當參數個數已知的時候能夠用call
,而當參數個數不肯定的時候能夠用apply
。bind
和call
很類似,第一個參數是this
的指向,從第二個參數開始是接收的參數列表。區別在於bind
方法返回值是函數以及bind
接收的參數列表的使用。bind
方法不會當即執行,而是返回一個改變了上下文 this
後的函數。而不會影響原函數中的this
指向。最後咱們再看一個完整的實例來表現這個三個函數的用途和區別:函數
function sub(a, b) { const sub = a + b console.log(sub) return sub } sub.call(null, 1, 2) sub.apply(null, [1, 2]) sub.bind(null, 1, 2)()
能夠看到,call
和apply
參數不同,而bind
參數和call
同樣,但還須要單獨調用一下函數。學習
var arr = [0,8,3,46] var max = Math.max.apply(null,arr);//46 var min = Math.min.apply(null,arr);//0 // 等價於 var max = window.Math.max(...arr); var min = window.Math.min(...arr);
這裏利用apply
的第二個參數是接受一個數組,而在調用函數的時候會自動展開這個數組,而max和min
方法接受參數的形式是(1,2,3,4)。
var trueArr = Array.prototype.slice.call(arguments,0,arguments.length)
function isArray(obj){ return Object.prototype.toString.call(obj) == '[object Array]'; } isArray([]) // true isArray('dot') // false
function log(){ console.log.apply(console, arguments); }
以上用途參考:call、apply 和 bind 方法的用法以及區別this
call
、apply
、bind
都是爲了改變當前要執行函數this
指向,由第一個參數決定,爲null
或者undefined
時則爲window
對象。call
和apply
的參數有區別。而bind
不是立刻執行函數,而是返回該函數和保留該函數的執行上下文。spa
學習如逆水行舟,不進則退,前端技術飛速發展,若是天天不堅持學習,就會跟不上,我會陪着你們,天天堅持推送博文,跟你們一同進步,但願你們能關注我,第一時間收到最新文章。
我的公衆號: