亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

手寫call、apply、bind函數(shù)

gecko23 / 3386人閱讀

摘要:函數(shù)特點(diǎn)可以改變我們當(dāng)前函數(shù)的指向還會(huì)讓當(dāng)前函數(shù)執(zhí)行題目自測(cè)思路解析執(zhí)行傳入三個(gè)參數(shù)函數(shù)內(nèi)部執(zhí)行傳入三個(gè)參數(shù)函數(shù)內(nèi)部執(zhí)行

call函數(shù)

特點(diǎn):

1)可以改變我們當(dāng)前函數(shù)的this指向

2)還會(huì)讓當(dāng)前函數(shù)執(zhí)行

Function.prototype.call = function (context) {
 if (typeof this !== "function") {
    throw new TypeError(`${this} is not a function`)
  }
  context = Object(context) || window;
  context.fn = this;
  let args = [];
  for (let i = 1; i < arguments.length; i++) {
    args.push("arguments["+i+"]"); 
  }
  let r = eval("context.fn("+args+")");
  delete context.fn;
  return r;
}

題目自測(cè)

function fn1() {
  console.log(this,arguments);
  console.log(1);
  
}
function fn2() {
  console.log(this,arguments);
  console.log(2);
}
fn1.call(fn2,1,2); // fn2 [1,2] 1
fn1.call.call.call.call.call(fn2,1,2); // {number:1} [2] 2

思路解析

fn1.call(fn2,1,2)

1)call執(zhí)行傳入fn2,1,2三個(gè)參數(shù)

2)call函數(shù)內(nèi)部context = Object(fn2) = fn2

3)fn2.fn = fn1

4)args=["arguments[1]","arguments[2]"]=[1,2]

5)eval("context.fn("+args+")") = fn2.fn(1,2) = fn2.fn1(1,2)

fn1.call.call.call.call.call(fn2,1,2)

1)call執(zhí)行傳入fn2,1,2三個(gè)參數(shù)

2)call函數(shù)內(nèi)部context = Object(fn2) = fn2

3)fn2.fn = call

4)args=["arguments[1]",arguments[2]]=[1,2]

5)eval("context.fn("+args+")") = fn2.fn(1,2) = fn2.call(1,2)

6)call執(zhí)行傳入1,2兩個(gè)參數(shù)

7)call函數(shù)內(nèi)部context = Object(1) = Number{1}

8)Number{1}.fn = fn2

9)args=["arguments[1]"]=[1]

10)eval("context.fn("+args+")") = Number{1}.fn(2) = Number{1}.fn2(2)

注:多次調(diào)用call的時(shí)候其實(shí)是call執(zhí)行的時(shí)候內(nèi)部又調(diào)用了一次call,總共調(diào)用兩次

apply函數(shù)

特點(diǎn):

1)可以改變我們當(dāng)前函數(shù)的this指向

2)還會(huì)讓當(dāng)前函數(shù)執(zhí)行

Function.prototype.apply = function (context,args) {
  if (typeof this !== "function") {
     throw new TypeError(`${this} is not a function`)
   }
   context = Object(context) || window;
   context.fn = this;
   if(!args){
    return context.fn();
   }
   let r = eval("context.fn("+args+")");
   delete context.fn;
   return r;
 }
new操作符

特點(diǎn)

新生成了對(duì)象

鏈接到原型

綁定this

返回一個(gè)對(duì)象

/*
 *基本使用 
 */
function Animal(type) {
  this.type = type ; 
}
Animal.prototype.say = function () {
  console.log("say");
}
let tiger = new Animal("tiger");
console.log(tiger);
--------------------------------------------------------
/*
 *方法實(shí)現(xiàn)
 */
function mockNew(){
    let Constructor = [].shift.call(arguments);
    let obj = {}; // 新生成了對(duì)象
    obj.__proto__ = Constructor.prototype; // 鏈接到原型
    let r = Constructor.apply(obj,arguments) // 綁定`this`
    return r instance Object ");//返回一個(gè)對(duì)象
}
let tiger = mockNew(Animal,"tiger");
console.log(tiger);
bind函數(shù)

特點(diǎn)

綁定this指向

返回一個(gè)綁定后的函數(shù)(高階函數(shù)原理)

如果綁定的函數(shù)被new執(zhí)行 ,當(dāng)前函數(shù)的this就是當(dāng)前的實(shí)例

new出來(lái)的結(jié)果可以找到原有類的原型

Function.prototype.bind = function (context) {
  if (typeof this !== "function") {
    throw new TypeError(`${this} is not a function`)
  }
  let that = this;
  let bindArgs = Array.prototype.slice.call(arguments, 1);
  function Fn() { };
  function bindFn() {
    let args = Array.prototype.slice.call(arguments);
    /*
     * 綁定`this`指向
     * 如果綁定的函數(shù)被`new`執(zhí)行 ,當(dāng)前函數(shù)的`this`就是當(dāng)前的實(shí)例
     */
    that.apply(this instanceof bindFn ");this : context, bindArgs.concat(args)); 
  }
  /*`new`出來(lái)的結(jié)果可以找到原有類的原型*/
  Fn.prototype = that.prototype; 
  bindFn.prototype = new Fn();
  /*返回一個(gè)綁定后的函數(shù)*/
  return bindFn; 
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/6988.html

相關(guān)文章

  • 如何手寫call、apply、bind?

    摘要:可以改變,并且傳入?yún)?shù),立刻執(zhí)行,返回函數(shù)返回值手寫參數(shù)默認(rèn)值并不會(huì)排除,所以重新賦值是調(diào)用的函數(shù)執(zhí)行后刪除新增屬性可以改變,并且傳入?yún)?shù),與不同的是,傳入的參數(shù)是數(shù)組或類數(shù)組,立刻執(zhí)行,返回函數(shù)返回值手寫參數(shù)默認(rèn)值并不會(huì)排除,所以重新賦值 call Function.prototype.call(this, arg1, arg2, …..)可以改變this,并且傳入?yún)?shù),立刻執(zhí)行,返...

    VEIGHTZ 評(píng)論0 收藏0
  • js函數(shù)this理解?手寫apply、call、bind就夠了

    摘要:一是什么函數(shù)的內(nèi)部屬性,引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象。函數(shù)做為節(jié)點(diǎn)事件調(diào)用時(shí)指向節(jié)點(diǎn)本身做為構(gòu)造函數(shù)實(shí)力化方法時(shí)指向?qū)嵗龑?duì)象箭頭函數(shù)里的普通函數(shù),由于閉包函數(shù)是執(zhí)行的,所以指向箭頭函數(shù)的指向函數(shù)創(chuàng)建時(shí)的作用域。 一、this是什么? 函數(shù)的內(nèi)部屬性,this引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象。也就是說(shuō)函數(shù)的this會(huì)指向調(diào)用函數(shù)的執(zhí)行環(huán)境。 function a(){ retur...

    Cciradih 評(píng)論0 收藏0
  • 手寫call、apply、bind及相關(guān)面試題解析

    摘要:我是前端我的全名是我是一個(gè)前端指向接收多個(gè)參數(shù),第一個(gè)是返回值返回值是一個(gè)函數(shù)上下文的,不會(huì)立即執(zhí)行??吕锘嚓P(guān)講解請(qǐng)移步簡(jiǎn)版的實(shí)現(xiàn)就算完成了歡迎吐槽點(diǎn)贊 它們有什么不同?怎么用? call 接收多個(gè)參數(shù),第一個(gè)為函數(shù)上下文也就是this,后邊參數(shù)為函數(shù)本身的參數(shù)。 let obj = { name: 一個(gè) } ...

    TwIStOy 評(píng)論0 收藏0
  • 手寫JavaScript中的bind方法

    摘要:如果綁定后的函數(shù)被了,那么此時(shí)指向就發(fā)生改變。構(gòu)造函數(shù)上的屬性和方法,每個(gè)實(shí)例上都有。接下來(lái)聲明一個(gè)函數(shù),在該中獲取了第二次傳的參數(shù),并且返回了的執(zhí)行。的又等于的實(shí)例。至此,就實(shí)現(xiàn)了自己的方法。 之前已經(jīng)實(shí)現(xiàn)過了call,apply和new。今天順便把bind也實(shí)現(xiàn)下。首先: bind方法返回的是一個(gè)綁定this后的函數(shù),并且該函數(shù)并沒有執(zhí)行,需要手動(dòng)去調(diào)用。(從這一點(diǎn)看bind函數(shù)...

    AZmake 評(píng)論0 收藏0
  • 面試題里的那些各種手寫

    摘要:最近準(zhǔn)備初級(jí)前端面試,發(fā)現(xiàn)有很多手寫實(shí)現(xiàn)什么的,例如什么手寫實(shí)現(xiàn),。后面以這道題為引線面試官可能會(huì)追問什么是執(zhí)行上下文的判斷,的區(qū)別手寫一個(gè)函數(shù)實(shí)現(xiàn)斐波那契數(shù)列首先拷一個(gè)阮神在他教程里的一個(gè)寫法。 最近準(zhǔn)備初級(jí)前端面試,發(fā)現(xiàn)有很多手寫實(shí)現(xiàn)什么的,例如什么手寫實(shí)現(xiàn)bind,promise。手寫ajax,手寫一些算法。翻閱了很多書籍和博客。 這里做一個(gè)總結(jié)改進(jìn),算是對(duì)我后面大概為期一個(gè)月找...

    wh469012917 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<