函數調用方法 在談論JavaScript中apply、call和bind這三兄弟之前,我想先說下,函數的調用方式有哪些: 作為函數 作為方法 作為構造函數 通過它們的call()和apply()方法間接調用 前面的三種調用方法,我們都知道且不在這篇文章的討論範圍內,就不說了。 下麵我們來說說這第四種 ...
函數調用方法
在談論JavaScript中apply、call和bind這三兄弟之前,我想先說下,函數的調用方式有哪些:
- 作為函數
- 作為方法
- 作為構造函數
- 通過它們的call()和apply()方法間接調用
前面的三種調用方法,我們都知道且不在這篇文章的討論範圍內,就不說了。
下麵我們來說說這第四種調用方法
通過call()和apply()間接調用
其實,我們可以將這兩個函數看做是某個對象的方法,通過調用方法的方式來間接調用函數:
function f(){} f.call(o); f.apply(o);
call()和apply()的第一個參數是要調用函數的母對象,它是調用上下文,在函數體內通過this來獲得對它的引用。
那麼他們是一樣的,還是有區別的,還有bind方法呢?君莫急,下麵詳細的解析他們三者的區別和聯繫。
call()
call()方法給調用它的方法指定特定的this指針(習慣用語,不要和我糾結它的正確性)和參數。例如有這麼一個函數:
var fn = function (arg1, arg2) { console.log(this, arg1, arg2); }
我來調用它:
fn.call(null, 'Skylor', 'min'); //1 fn.call(undefined, 'Skylor', 'min'); //2 var fx = function() {} fn.call(fx, 'Skylor', 'min'); //3
這三個call方法的返回值是什麼呢?不廢話,請看:
1. null "Skylor" "min"
2. undefined "Skylor" "min"
3. fx "Skylor" "min"
真的是這樣嗎,機智的你,去瀏覽器控制台小試了一下,我去,你這坑貨,不是這樣的:
chrome
1. Window "Skylor" "min"
2. Window "Skylor" "min"
3. fx "Skylor" "min"
好吧,你機智。但這已經很好的說明瞭call方法了。(window很高級,微軟偷笑中...)
我們註意到call方法,第一個參數是指定this指針,後面每個參數指定需要的參數,註意我用的是“每個”,這意味著你需要幾個參數就要想調用函數那樣,一個個參數寫進去。
apply()
apply()是call()的兄弟啊,其他地方長的都一樣,都是男的,就一個地方不一樣。先看例子:
fn.apply(null, ['Skylor', 'min']); //1 fn.apply(fx, ['Skylor', 'min']); //2
哥們,你是不是寫錯了,多了個中括弧啊。不,不,不,這就是他和call長的不一樣的地方,它的第二個參數是個需要的參數Array。
bind()
bind()嘛,他們三個不是仨兄弟嘛,,這個我懂,blabla....不不不,它是和apply、call結拜的兄弟,不是親兄弟。
當然,bind方法也是允許你指定this指針,但是它不是調用函數,而是返回一個(或者說是拷貝)調用它的函數的函數,並給這個函數指定特定的this指針和參數。慣例,例子說明一切:
var fnbound = fn.bind(null, 'Skylor', 'min');
這時,fnbound是一個函數,一個this指向null,參數為['Skylor', 'min']的另一個函數。調用之:
fnbound();
結果:
null, 'Skylor', 'min'
不要和我糾結Window的事了。。。。。
bind和其他兩個兄弟不一樣的地方,是,它不是調用函數,而是返回一個新的函數,同樣,它也是指定this指針和參數的,指定參數的方式和call一樣,是一個一個來的。
最後來一個例子唄:
var shoppingCart = (function(){ var _calculatePrice = function () { return this.price * this.amount; }; return { calculatePrice : _calculatePrice } })(); var goods = { name : ‘hammer’, price: 199, amount : 2 }; shoppingCart.calculatePrice.call(goods);
OK,以上是我的見解,如有不正確的地方,歡迎指正和批評,不甚歡喜與感謝。By Skylormin