javascript中函數(shù)的call/apply/bind方法

call/apply/bind的方法來源

call/apply/bind方法其實(shí)都來自與function.prototype,都屬于實(shí)例方法

   console.log(Function.prototype.hasOwnproperty('call'));
   console.log(Function.prototype.hasOwnproperty('apply'));
   console.log(Function.prototype.hasOwnproperty('bind'));
   //true  true  true

擴(kuò)展一下下:

Object.prototype.hasOwnProperty()方法用來判斷某個(gè)對(duì)象是否含有指定的自身屬性,返回true/false.
Object.prototype.isPrototypeOf()方法測(cè)試一個(gè)對(duì)象是否存在另一個(gè)對(duì)象的原型鏈上,返回true/false.

Function.prototype.call()

函數(shù)實(shí)例的call方法,可以指定函數(shù)this的指向,既函數(shù)執(zhí)行時(shí)的作用域诀紊。然后在指定的作用域內(nèi)調(diào)用該函數(shù),而且立即執(zhí)行。

   var  obj = {
          num:123
}
  var num = 456;
  functon fn(){
    console.log(this.num)
}
fn() //456
fn.call() //456
fn.call(null)//456
fn.call(undefined)//456
fn.call(this)//456
fn.call(obj)//123

從上邊可以看出fn函數(shù)的this在沒有操作或者call中的參數(shù)為空叨橱、null、undefined断盛、this的時(shí)候都指向的應(yīng)該是456罗洗。而當(dāng)參數(shù)改變。fn中this的指向改變钢猛,指向的是obj伙菜。所以是123.

call()方法可以傳遞兩個(gè)參數(shù)。第一個(gè)參數(shù)是指定函數(shù)內(nèi)部中this的指向(也就是函數(shù)執(zhí)行時(shí)所在的作用域)命迈,第二個(gè)參數(shù)是函數(shù)調(diào)用時(shí)需要傳遞的參數(shù)贩绕。
第一個(gè)參數(shù)是必須的,可以是null壶愤,undefined淑倾,this,但是不能為空征椒。設(shè)置為null娇哆,undefined,this表明函數(shù)keith此時(shí)處于全局作用域勃救。第二個(gè)參數(shù)中必須一個(gè)個(gè)添加碍讨。而在apply中必須以數(shù)組的形式添加。

Function.prototype.apply()

apply方法的作用與call方法類似剪芥,也是改變this指向(函數(shù)執(zhí)行時(shí)所在的作用域)垄开,然后在指定的作用域中,調(diào)用該函數(shù)税肪。同時(shí)也會(huì)立即執(zhí)行該函數(shù)溉躲。唯一的區(qū)別就是,它接收一個(gè)數(shù)組作為函數(shù)執(zhí)行時(shí)的參數(shù)益兄。
apply方法的實(shí)例應(yīng)用
   找出數(shù)組中最大的數(shù)
  var arr = [1,2,3,4,58,6]
console.log(Math.max.apply(null,arr))

Javascript中是沒有提供找出數(shù)組中最大值的方法的锻梳,結(jié)合使用繼承自Function.prototype的apply和Math.max方法,就可以返回?cái)?shù)組的最大值净捅。

   將數(shù)組的空元素變?yōu)閡ndefined
console.log(Array.apply(null, [1, , 3])); // [1, undefined, 3]

空元素與undefined的差別在于疑枯,數(shù)組的forEach方法會(huì)跳過空元素,但是不會(huì)跳過undefined和null蛔六。因此荆永,遍歷內(nèi)部元素的時(shí)候废亭,會(huì)得到不同的結(jié)果。

var a = [1, , 3];
 a.forEach(function(index) {
 console.log(index); //1,3 具钥,跳過了空元素豆村。
 })
 Array.apply(null,a).forEach(function(index){
 console.log(index); ////1,undefined,3 做入,將空元素設(shè)置為undefined
 })
   轉(zhuǎn)換類似數(shù)組的對(duì)象

利用數(shù)組對(duì)象的slice方法立膛,可以將一個(gè)類似數(shù)組的對(duì)象(比如arguments對(duì)象)轉(zhuǎn)為真正的數(shù)組。當(dāng)然记餐,slice方法的一個(gè)重要應(yīng)用宁玫,就是將類似數(shù)組的對(duì)象轉(zhuǎn)為真正的數(shù)組粗恢。call和apply都可以實(shí)現(xiàn)該應(yīng)用。

console.log(Array.prototype.slice.apply({0:1,length:1})); //[1]
console.log(Array.prototype.slice.call({0:1,length:1})); //[1]
console.log(Array.prototype.slice.apply({0:1,length:2})); //[1,undefined]
console.log(Array.prototype.slice.call({0:1,length:2})); //[1,undefined]
function keith(a,b,c){
 return arguments;
 }
console.log(Array.prototype.slice.call(keith(2,3,4))); //[2,3,4]

上面代碼的call欧瘪,apply方法的參數(shù)都是對(duì)象眷射,但是返回結(jié)果都是數(shù)組,這就起到了將對(duì)象轉(zhuǎn)成數(shù)組的目的恋追。從上面代碼可以看到凭迹,這個(gè)方法起作用的前提是罚屋,被處理的對(duì)象必須有l(wèi)ength屬性苦囱,以及相對(duì)應(yīng)的數(shù)字鍵。

Function.prototype.bind()

bind方法用于指定函數(shù)內(nèi)部的this指向(執(zhí)行時(shí)所在的作用域)脾猛,然后返回一個(gè)新函數(shù)撕彤。bind方法并非立即執(zhí)行一個(gè)函數(shù)。
var keith = {
 a: 1,
 count: function() {
 console.log(this.a++);
 }
 };
 keith.count(); //1
 keith.count(); //2
 keith.count(); //3

上面代碼中猛拴,如果this.a指向keith對(duì)象內(nèi)部的a屬性羹铅,如果這個(gè)方法賦值給另外一個(gè)變量,調(diào)用時(shí)就會(huì)出錯(cuò)愉昆。

var keith = {
a: 1,
count: function() {
console.log(this.a++);
}
};
var f = keith.count;
f(); //NaN

上面代碼中职员,如果把count方法賦值給f變量,那么this對(duì)象指向不再是keith對(duì)象了跛溉,而是window對(duì)象焊切。而window.a默認(rèn)為undefined,進(jìn)行遞增運(yùn)算之后undefined++就等于NaN芳室。

為了解決這個(gè)問題专肪,可以使用bind方法,將keith對(duì)象里的this綁定到keith對(duì)象上堪侯,或者是直接調(diào)用嚎尤。

var f = keith.count.bind(keith);
f(); //1
f(); //2
f(); //3
keith.count.bind(keith)() //1
keith.count.bind(keith)() //2
keith.count.bind(keith)() //3

當(dāng)然,this也可以綁定到其他對(duì)象上伍宦。

var obj = {
a: 100
};
var f = keith.count.bind(obj);
f(); //100
f(); //101
f(); //102

同樣芽死,我們也可以給bind方法傳遞參數(shù)乏梁,第一個(gè)參數(shù)如果為null或者undefined或者this,會(huì)將函數(shù)內(nèi)部的this對(duì)象指向全局環(huán)境关贵;第二個(gè)為調(diào)用時(shí)需要的參數(shù)掌呜,并且傳遞參數(shù)的形式與call方法相同。

function keith(a, b) {
return a + b;
}
console.log(keith.apply(null,[1,4])); //5
console.log(keith.call(null,1,4)); //5
console.log(keith.bind(null, 1, 4)); //keith()
console.log(keith.bind(null, 1, 4)()); //5

綁定回調(diào)函數(shù)的對(duì)象

var o = {
 f: function() {
 console.log(this === o);
 }
 }
 $('#button').on('click', function() {
 o.f.apply(o);
 //或者 o.f.call(o);
 //或者 o.f.bind(o)();
 });
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末坪哄,一起剝皮案震驚了整個(gè)濱河市质蕉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翩肌,老刑警劉巖模暗,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異念祭,居然都是意外死亡兑宇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門粱坤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隶糕,“玉大人,你說我怎么就攤上這事站玄∶蹲ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵株旷,是天一觀的道長再登。 經(jīng)常有香客問我,道長晾剖,這世上最難降的妖魔是什么锉矢? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮齿尽,結(jié)果婚禮上沽损,老公的妹妹穿的比我還像新娘。我一直安慰自己循头,他們只是感情好绵估,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贷岸,像睡著了一般壹士。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上偿警,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天躏救,我揣著相機(jī)與錄音,去河邊找鬼。 笑死盒使,一個(gè)胖子當(dāng)著我的面吹牛崩掘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播少办,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苞慢,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了英妓?” 一聲冷哼從身側(cè)響起挽放,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔓纠,沒想到半個(gè)月后辑畦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腿倚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年纯出,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敷燎。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡暂筝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硬贯,到底是詐尸還是另有隱情焕襟,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布澄成,位于F島的核電站胧洒,受9級(jí)特大地震影響畏吓,放射性物質(zhì)發(fā)生泄漏墨状。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一菲饼、第九天 我趴在偏房一處隱蔽的房頂上張望肾砂。 院中可真熱鬧,春花似錦宏悦、人聲如沸镐确。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽源葫。三九已至,卻和暖如春砖瞧,著一層夾襖步出監(jiān)牢的瞬間息堂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荣堰,地道東北人床未。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像振坚,于是被迫代替她去往敵國和親薇搁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容