call()缸榄、apply()、bind()

Function.prototype.call()

call() 方法在使用一個指定的this值和若干個指定的參數(shù)值的前提下調(diào)用某個函數(shù)或方法.

fun.call(thisArg[, arg1[, arg2[, ...]]])
  • 參數(shù)

    • thisArg
      • 在fun函數(shù)運行時指定的this值巾乳。需要注意的是您没,指定的this值并不一定是該函數(shù)執(zhí)行時真正的this值,如果這個函數(shù)處于非嚴(yán)格模式下胆绊,則指定為null和undefined的this值會自動指向全局對象(瀏覽器中就是window對象)氨鹏,同時值為原始值(數(shù)字,字符串压状,布爾值)的this會指向該原始值的自動包裝對象仆抵。
    • arg1, arg2, ...
      • 指定的參數(shù)列表。
  • 返回值

    • 返回結(jié)果包括制定的this值和參數(shù)种冬。
  • 描述

    • 可以讓call()中的對象調(diào)用當(dāng)前對象所擁有的function镣丑。你可以使用call()來實現(xiàn)繼承:寫一個方法,然后讓另外一個新的對象來繼承它(而不是在新對象中再寫一次這個方法)娱两。
function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError('Cannot create product ' +
                      this.name + ' with a negative price');
  }
}

function Food(name, price) {
  Product.call(this, name, price); 
  this.category = 'food';
}

//等同于
function Food(name, price) { 
    this.name = name;
    this.price = price;
    if (price < 0) {
        throw RangeError('Cannot create product ' +
                this.name + ' with a negative price');
    }

    this.category = 'food'; 
}

//function Toy 同上
function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

Function.prototype.apply()

apply() 方法在指定 this 值和參數(shù)(參數(shù)以數(shù)組或類數(shù)組對象的形式存在)的情況下調(diào)用某個函數(shù)莺匠。

fun.apply(thisArg[, argsArray])
  • 參數(shù)
    • thisArg
      • 在 fun 函數(shù)運行時指定的 this 值。需要注意的是十兢,指定的 this 值并不一定是該函數(shù)執(zhí)行時真正的 this 值趣竣,如果這個函數(shù)處于非嚴(yán)格模式下,則指定為 null 或 undefined 時會自動指向全局對象(瀏覽器中就是window對象)旱物,同時值為原始值(數(shù)字期贫,字符串,布爾值)的 this 會指向該原始值的自動包裝對象异袄。
    • argsArray
      • 一個數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為單獨的參數(shù)傳給 fun 函數(shù)玛臂。如果該參數(shù)的值為null 或 undefined烤蜕,則表示不需要傳入任何參數(shù)。從ECMAScript 5 開始可以使用類數(shù)組對象迹冤。
  • 描述
    • 在調(diào)用一個存在的函數(shù)時讽营,你可以為其指定一個 this 對象。 this 指當(dāng)前對象泡徙,也就是正在調(diào)用這個函數(shù)的對象橱鹏。 使用 apply, 你可以只寫一次這個方法然后在另一個對象中繼承它堪藐,而不用在新對象中重復(fù)寫該方法莉兰。
Function.prototype.construct = function (aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

// 在全局Function上添加一個方法,對所有Function有效
// this 指向調(diào)用方法的對象
// oNew是以這個對象的原型為原型構(gòu)造出來的新對象礁竞,
// this.apply(oNew,aArgs) 調(diào)用this指向的函數(shù)對象糖荒,并把這個函數(shù)對象的this直線oNew,以aArgs里的成員作為函數(shù)的參數(shù)
// 這個方法返回這個新對象

function MyConstructor () {
    for (var nProp = 0; nProp < arguments.length; nProp++) {
        this["property" + nProp] = arguments[nProp];
    }
}

// 聲明一個構(gòu)造函數(shù)模捂,并解析傳入的參數(shù)

var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);
// 調(diào)用構(gòu)造函數(shù)的construct()方法
// 這個方法首先以這個函數(shù)為原型構(gòu)造一個新對象oNew
// 再以oNew作為this指向捶朵,myArray里的元素作為參數(shù)調(diào)用這個函數(shù)
// 運行結(jié)果oNew {property0: 4, property1: "Hello world!", property2: false}
// 把這個對象返回蜘矢,賦值給myInstance

Function.prototype.bind()

bind()方法會創(chuàng)建一個新函數(shù),當(dāng)這個新函數(shù)被調(diào)用時综看,它的this值是傳遞給bind()的第一個參數(shù), 它的參數(shù)是bind()的其他參數(shù)和其原本的參數(shù).

fun.bind(thisArg[, arg1[, arg2[, ...]]])

參數(shù)

  • thisArg

    • 當(dāng)綁定函數(shù)被調(diào)用時品腹,該參數(shù)會作為原函數(shù)運行時的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時红碑,該參數(shù)無效舞吭。
  • arg1, arg2, ...

    • 當(dāng)綁定函數(shù)被調(diào)用時,這些參數(shù)加上綁定函數(shù)本身的參數(shù)會按照順序作為原函數(shù)運行時的參數(shù)句喷。
  • 返回值

    • 返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝
  • 描述

    • bind() 函數(shù)會創(chuàng)建一個新函數(shù)(稱為綁定函數(shù))镣典,新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標(biāo)函數(shù))具有相同的函數(shù)體(在 ECMAScript 5 規(guī)范中內(nèi)置的call屬性)。當(dāng)目標(biāo)函數(shù)被調(diào)用時 this 值綁定到 bind() 的第一個參數(shù)唾琼,該參數(shù)不能被重寫兄春。綁定函數(shù)被調(diào)用時,bind() 也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)锡溯。一個綁定函數(shù)也能使用new操作符創(chuàng)建對象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器赶舆。提供的 this 值被忽略,同時調(diào)用時的參數(shù)被提供給模擬函數(shù)祭饭。

bind 兼容寫法

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), //獲取第二個起的函數(shù)參數(shù)
        fToBind = this, //獲取要綁定的函數(shù)
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP ? this : oThis || this,
            //this指向函數(shù)的調(diào)用者芜茵,當(dāng)函數(shù)普通調(diào)用時,this指向 oThis || this
            //作為構(gòu)造函數(shù)調(diào)用時 this指向構(gòu)造出來的新對象
            //新對象的原型指向fNOP的實例
            //fNOP的實例的原型又指向綁定函數(shù)的原型
            //使用綁定后函數(shù)構(gòu)造出來的新對象的原型也指向綁定函數(shù)的原型
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;// 把fNOP的原型指向綁定的函數(shù)
    fBound.prototype = new fNOP(); //把fBound的原型指向fNOP構(gòu)造出來的新對象 
         //fBound的原型被指定為new fNOP()倡蝙,
          //也就是說如果我們綁定了一個構(gòu)造函數(shù)A得到新的構(gòu)造函數(shù)B九串,則使用B構(gòu)造的對象仍然會是A的實例,只不過原型鏈被new fNOP插了一腳
        //反正new fNOP()本身是{}沒有什么屬性寺鸥,插這一腳不影響新對象的使用
    return fBound;
  };
}

// 簡單寫法
if(!Function.prototype.bind){
    Function.prototype.bind = function (obj) {
        var arr = Array.prototype.slice.call(arguments,1),
            _self=this,
            return function(){
                _self.apply(obj,arr.concat(Array.prototype.silce.call(arguments)));
            }
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猪钮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胆建,更是在濱河造成了極大的恐慌烤低,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笆载,死亡現(xiàn)場離奇詭異扑馁,居然都是意外死亡,警方通過查閱死者的電腦和手機凉驻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門腻要,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涝登,你說我怎么就攤上這事闯第。” “怎么了缀拭?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵咳短,是天一觀的道長填帽。 經(jīng)常有香客問我,道長咙好,這世上最難降的妖魔是什么篡腌? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮勾效,結(jié)果婚禮上嘹悼,老公的妹妹穿的比我還像新娘。我一直安慰自己层宫,他們只是感情好杨伙,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著萌腿,像睡著了一般限匣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毁菱,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天米死,我揣著相機與錄音,去河邊找鬼贮庞。 笑死峦筒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窗慎。 我是一名探鬼主播物喷,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼遮斥!你這毒婦竟也來了峦失?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤伏伐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晕拆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藐翎,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年实幕,在試婚紗的時候發(fā)現(xiàn)自己被綠了吝镣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昆庇,死狀恐怖末贾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情整吆,我是刑警寧澤拱撵,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布辉川,位于F島的核電站,受9級特大地震影響拴测,放射性物質(zhì)發(fā)生泄漏乓旗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一集索、第九天 我趴在偏房一處隱蔽的房頂上張望屿愚。 院中可真熱鬧,春花似錦务荆、人聲如沸妆距。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娱据。三九已至,卻和暖如春浦箱,著一層夾襖步出監(jiān)牢的瞬間吸耿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工酷窥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咽安,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓蓬推,卻偏偏與公主長得像妆棒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沸伏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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