最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

apply?call?bind方法原理及使用場(chǎng)景示例詳解

 更新時(shí)間:2023年08月30日 08:48:44   作者:codeteenager  
這篇文章主要為大家介紹了apply&call&bind方法原理及使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

call、apply 和 bind 是掛在 Function 對(duì)象上的三個(gè)方法,調(diào)用這三個(gè)方法的必須是一個(gè)函數(shù)。

基本用法如下:

func.call(thisArg, param1, param2, ...)
func.apply(thisArg, [param1,param2,...])
func.bind(thisArg, param1, param2, ...)

其中 func 是要調(diào)用的函數(shù),thisArg 一般為 this 所指向的對(duì)象,后面的 param1、2 為函數(shù) func 的多個(gè)參數(shù),如果 func 不需要參數(shù),則后面的 param1、2 可以不寫。

這三個(gè)方法共有的、比較明顯的作用就是,都可以改變函數(shù) func 的 this 指向。call 和 apply 的區(qū)別在于,傳參的寫法不同:apply 的第 2 個(gè)參數(shù)為數(shù)組; call 則是從第 2 個(gè)至第 N 個(gè)都是給 func 的傳參;而 bind 和這兩個(gè)(call、apply)又不同,bind 雖然改變了 func 的 this 指向,但不是馬上執(zhí)行,而這兩個(gè)(call、apply)是在改變了函數(shù)的 this 指向之后立馬執(zhí)行。

這三個(gè)方法的理念都是借用方法的思路,例如A 對(duì)象有個(gè) getName 的方法,B 對(duì)象也需要臨時(shí)使用同樣的方法,那么這時(shí)候我們是單獨(dú)為 B 對(duì)象擴(kuò)展一個(gè)方法,還是借用一下 A 對(duì)象的方法呢?當(dāng)然是可以借用 A 對(duì)象的 getName 方法,既達(dá)到了目的,又節(jié)省重復(fù)定義,節(jié)約內(nèi)存空間。

方法/特征callapplybind
方法參數(shù)多個(gè)單個(gè)數(shù)組多個(gè)
方法功能函數(shù)調(diào)用改變this函數(shù)調(diào)用改變this函數(shù)調(diào)用改變this
返回結(jié)果的直接執(zhí)行的直接執(zhí)行返回待執(zhí)行函數(shù)
底層實(shí)現(xiàn)通過eval通過eval間接調(diào)用apply

應(yīng)用場(chǎng)景

我們來看看應(yīng)用場(chǎng)景有哪些?

判斷數(shù)據(jù)類型

用 Object.prototype.toString 來判斷類型是最合適的,借用它我們幾乎可以判斷所有類型的數(shù)據(jù)。

function getType(obj){
  let type  = typeof obj;
  if (type !== "object") {
    return type;
  }
  return Object.prototype.toString.call(obj).replace(/^$/, '$1');
}

判斷數(shù)據(jù)類型就是借用了 Object 的原型鏈上的 toString 方法,最后返回用來判斷傳入的 obj 的字符串,來確定最后的數(shù)據(jù)類型。

類數(shù)組借用方法

類數(shù)組因?yàn)椴皇钦嬲臄?shù)組,所有沒有數(shù)組類型上自帶的種種方法,所以我們就可以利用一些方法去借用數(shù)組的方法,例如:

var arrayLike = { 
  0: 'java',
  1: 'script',
  length: 2
} 
Array.prototype.push.call(arrayLike, 'jack', 'lily'); 
console.log(typeof arrayLike); // 'object'
console.log(arrayLike);
// {0: "java", 1: "script", 2: "jack", 3: "lily", length: 4}

arrayLike 是一個(gè)對(duì)象,模擬數(shù)組的一個(gè)類數(shù)組。從數(shù)據(jù)類型上看,它是一個(gè)對(duì)象。從上面的代碼中可以看出,用 typeof 來判斷輸出的是 'object',它自身是不會(huì)有數(shù)組的 push 方法的,這里我們就用 call 的方法來借用 Array 原型鏈上的 push 方法,可以實(shí)現(xiàn)一個(gè)類數(shù)組的 push 方法,給 arrayLike 添加新的元素。

獲取數(shù)組的最大/最小值

我們可以用 apply 來實(shí)現(xiàn)數(shù)組中判斷最大 / 最小值,apply 直接傳遞數(shù)組作為調(diào)用方法的參數(shù),也可以減少一步展開數(shù)組,可以直接使用 Math.max、Math.min 來獲取數(shù)組的最大值 / 最小值,例如:

let arr = [13, 6, 10, 11, 16];
const max = Math.max.apply(Math, arr); 
const min = Math.min.apply(Math, arr);
console.log(max);  // 16
console.log(min);  // 6

apply和call的實(shí)現(xiàn)

apply 和 call 基本原理是差不多的,只是參數(shù)存在區(qū)別。

Function.prototype.call = function (context, ...args) {
  var context = context || window;
  context.fn = this;
  var result = eval('context.fn(...args)');
  delete context.fn
  return result;
}
Function.prototype.apply = function (context, args) {
  let context = context || window;
  context.fn = this;
  let result = eval('context.fn(...args)');
  delete context.fn
  return result;
}

實(shí)現(xiàn) call 和 apply 的關(guān)鍵就在 eval 這行代碼。其中顯示了用 context 這個(gè)臨時(shí)變量來指定上下文,然后還是通過執(zhí)行 eval 來執(zhí)行 context.fn 這個(gè)函數(shù),最后返回 result。

要注意這兩個(gè)方法和 bind 的區(qū)別就在于,這兩個(gè)方法是直接返回執(zhí)行結(jié)果,而 bind 方法是返回一個(gè)函數(shù),因此這里直接用 eval 執(zhí)行得到結(jié)果。

bind的實(shí)現(xiàn)

bind 的實(shí)現(xiàn)思路基本和 apply 一樣,但是在最后實(shí)現(xiàn)返回結(jié)果這里,bind 和 apply 有著比較大的差異,bind 不需要直接執(zhí)行,因此不再需要用 eval ,而是需要通過返回一個(gè)函數(shù)的方式將結(jié)果返回,之后再通過執(zhí)行這個(gè)結(jié)果,得到想要的執(zhí)行效果。

Function.prototype.bind = function (context, ...args) {
    if (typeof this !== "function") {
      throw new Error("this must be a function");
    }
    var self = this;
    var fbound = function () {
        self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
    }
    if(this.prototype) {
      fbound.prototype = Object.create(this.prototype);
    }
    return fbound;
}

實(shí)現(xiàn) bind 的核心在于返回的時(shí)候需要返回一個(gè)函數(shù),故這里的 fbound 需要返回,但是在返回的過程中原型鏈對(duì)象上的屬性不能丟失。因此這里需要用Object.create 方法,將 this.prototype 上面的屬性掛到 fbound 的原型上面,最后再返回 fbound。這樣調(diào)用 bind 方法接收到函數(shù)的對(duì)象,再通過執(zhí)行接收的函數(shù),即可得到想要的結(jié)果。

以上就是apply call bind方法原理及使用場(chǎng)景示例詳解的詳細(xì)內(nèi)容,更多關(guān)于apply call bind原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

旬邑县| 台江县| 盱眙县| 荣成市| 泰安市| 长海县| 大荔县| 安吉县| 武威市| 德昌县| 瓦房店市| 宁晋县| 武鸣县| 怀宁县| 田林县| 平陆县| 乳山市| 老河口市| 嵊州市| 耒阳市| 咸丰县| 马关县| 尼勒克县| 黄冈市| 迭部县| 福安市| 德州市| 桂平市| 内乡县| 利津县| 淮南市| 宁海县| 新余市| 抚远县| 东光县| 民乐县| 蒙山县| 玉山县| 多伦县| 昭苏县| 花垣县|