【call apply bind】源碼實(shí)現(xiàn)

call方法的實(shí)現(xiàn)

  Function.prototype.myCall = function (context) {
      //this 調(diào)用的函數(shù)
      //context 調(diào)用函數(shù)的對(duì)像

      // 判斷this是否為函數(shù)
      if (typeof this !== 'function') {
        throw TypeError('Error')
      }
      context = context || window
      //聲明一個(gè)Symbol 防止fn被占用
      const fn = Symbol('fn')
      //將函數(shù)添加成為contxt 對(duì)象的方法被調(diào)用
      context[fn] = this
      //獲取參數(shù)
      //const args = Array.prototype.slice.call(arguments, 1)
      //const args = Array.from(arguments).slice(1)
      const args = [...arguments].slice(1)
      //調(diào)用返回結(jié)果
      const result = context[fn](...args)
      //刪除方法
      delete context[fn]
      //返回結(jié)果
      return result
  }

apply方法實(shí)現(xiàn)

  Function.prototype.myApply = function (context){
    if (typeof this !== 'function') {
      throw TypeError('Error')
    }

    context = context || window

    const args = arguments[1]

    const fn = Symbol('fn')

    context[fn] = this

    const result = context[fn](...args)

    delete context[fn]

    return result

  }

bind方法實(shí)現(xiàn)

  Function.prototype.myBind = function (context){
    if (typeof this !== 'function') {
      throw TypeError('Error')
    }
    const args = [...arguments].slice(1)
    let _this = this

    return function F(){
      if (this instanceof F) {
        return new _this(...args, ...arguments)
      } else {
        return _this.call(context, ...args, ...arguments)
      }
    }
  }

  //例題
  function print(age) {
    console.log(this.name+ "" + age)
  }

  let obj = {
    name: "李華"
  }

  print.myCall(obj,1,2,3) //李華1
  print.myApply(obj,[3,2,1]) //李華3

new方法實(shí)現(xiàn)

  function myNew(){
    //創(chuàng)建一個(gè)新對(duì)象
    let obj = new Object()
    //獲取到構(gòu)造函數(shù)
    let Constructor = Array.prototype.shift.call(arguments)
    //將對(duì)象的__proto__(隱形原型屬性) == 構(gòu)造函數(shù)的 prototype 顯示原型屬性
    obj.__proto__ = Constructor.prototype
    //將構(gòu)造函數(shù)作為對(duì)象的方法被調(diào)用
    let ret = Constructor.apply(obj, arguments)
    // 如果構(gòu)造函數(shù)返回值是對(duì)象則返回這個(gè)對(duì)象爆侣,如果不是對(duì)象則返回新的實(shí)例對(duì)象
    return typeof ret === "object" && ret !== null ? ret : obj
  }

  //例題:
  // ========= 無(wú)返回值 =============
  // const testNewFun = function(name) {
  //   this.name = name;
  // };
  //
  // const newObj = myNew(testNewFun, 'foo');
  //
  // console.log(newObj); // { name: "foo" }
  // console.log(newObj instanceof testNewFun); // true

  // ========= 有返回值 =============
  const testNewFun = function(name) {
    this.name = name;
    return {};
  };

  const newObj = myNew(testNewFun, 'foo');

  console.log(newObj); // {}
  console.log(newObj instanceof testNewFun); // false

reduce實(shí)現(xiàn)

  Array.prototype.myReduce = function (callbackFn){
    let o = this
    let k = 0,
        kPresent = false,
        accumulator,
        initialValue = arguments.length > 0 ? arguments[1] : undefined,
        len = this.length

    if (typeof callbackFn !== 'function') {
        throw TypeError('Error')
    }

    if (len === 0 && initialValue !== undefined) {
        throw TypeError('Error')
    }

    if (initialValue !== undefined) {
        accumulator = initialValue
    } else {
        accumulator = o[k]
        ++k
    }

    while (k < len) {
        kPresent = o.hasOwnProperty(k)
        if (kPresent) {
            accumulator = callbackFn.apply(undefined, [accumulator, o[k], k, o])
        }
        ++k
    }

    return accumulator
  }

  const rReduce = ['1', null, undefined, , 3, 4].reduce((a, b) => a + b, 3);
  const mReduce = ['1', null, undefined, , 3, 4].myReduce((a, b) => a + b, 3);

  console.log(rReduce, mReduce)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耗拓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冈涧,老刑警劉巖碰煌,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叹卷,死亡現(xiàn)場(chǎng)離奇詭異撼港,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)骤竹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)帝牡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蒙揣,你說(shuō)我怎么就攤上這事靶溜。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵罩息,是天一觀的道長(zhǎng)嗤详。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瓷炮,這世上最難降的妖魔是什么葱色? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮娘香,結(jié)果婚禮上苍狰,老公的妹妹穿的比我還像新娘。我一直安慰自己茅主,他們只是感情好舞痰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布土榴。 她就那樣靜靜地躺著诀姚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玷禽。 梳的紋絲不亂的頭發(fā)上赫段,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音矢赁,去河邊找鬼糯笙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛撩银,可吹牛的內(nèi)容都是我干的给涕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼额获,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼够庙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起抄邀,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耘眨,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后境肾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體剔难,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年奥喻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了偶宫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡环鲤,死狀恐怖读宙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情楔绞,我是刑警寧澤结闸,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布唇兑,位于F島的核電站,受9級(jí)特大地震影響桦锄,放射性物質(zhì)發(fā)生泄漏扎附。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一结耀、第九天 我趴在偏房一處隱蔽的房頂上張望留夜。 院中可真熱鬧,春花似錦图甜、人聲如沸碍粥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嚼摩。三九已至,卻和暖如春矿瘦,著一層夾襖步出監(jiān)牢的瞬間枕面,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工缚去, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潮秘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓易结,卻偏偏與公主長(zhǎng)得像枕荞,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搞动,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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