call、apply、bind 學不會,來砍我!!!!——輕生前端

今天咱們來講一下call、apply、bind這三兄弟的功能和區別順便本身封裝一下es6

call

介紹一下大哥call的功能

~~無論是call、apply仍是bind做用都是爲了改變函數中this的指向 ,因此他們的做用實際上是大同小異滴! 先說call 舉個例子吧數組

function fn() {
        console.log(arguments)
        console.log(this)
    }

    var obj = {
        f: fn
    }
複製代碼

就說他吧你要是運行個fn.call(obj, 4, 4, 4)這個 按理說this應該指向'點'前邊的那位,可是呢我們用了call那可就不同了,this就會指向call後邊括號裏第一個參數,固然首先我們得保證那個函數不能是箭頭函數,箭頭函數嘛 無論咋樣this都指向他的上級,由此還得出一個結論 this的指向的權重!!! ---箭頭函數 > call(apply,bind)這三兄弟 >"點" 而後括號中除了第一個參數以外剩下的都是 傳進去的參數
=====總之括號裏:bash

」第一個參數用函數執行時this的指向 後邊的參數都是傳給前邊函數的實參「app

fn.call(obj, 4, 4, 4)他的結果就是4,4,4和obj了!函數

封裝一個我們本身的call

~~對了奧call apply bind 這三兄弟 都是存在Function的原型裏邊的,我想在座的各位應該都知道吧! 既然他存在在Function的原型裏邊 咱們不如 ? 嘿嘿嘿本身封裝一個? 說封就封!淦!ui

封裝以前加個小插曲es6中的...是剩餘運算符this

let a = ['apple','banana','orange'];

console.log(...a); //apple, banana, orange
複製代碼

就這麼用的!!spa

開始封裝!!prototype

Function.prototype.myCall = function (context, ...ary) {
        var key = Symbol()
        context[key] = this
        context[key](...ary)
        delete context[key]
    }
    fn.myCall(obj, 6, 6, 6)
複製代碼

就這點代碼就ok了 context是他的形參也就是咱們須要讓this指向的地方 ...ary是解構了除了第一項以後的實參code

//怎麼保證一個函數執行上下文是context context.qqq() qqq執行時裏邊的 this就是context 可是呢這個qqq頗有可能會和實參裏邊的屬性重複因此咱們用了Symbol這個東西他就是一個惟一的東西 就不會重複啦爲啥還要把他刪了呢
delete context[key]由於這樣咱們會在實參obj中加一個新的屬性 因此爲了避免改變他就再刪掉他

雖然封裝一個功能和call相同的函數像是在白白費力,明明用call就能夠解決咱們還封裝,沒事找個樂子嘛!也鍛鍊鍛鍊腦殼!

apply

而後我們開始介紹老二

~~爲啥說他三是三兄弟其實他們三真的很像 apply似於call 可是第二個參數是一個集合 (數組或者類數組),

fn.apply(obj, [6, 6, 6])

和call同樣同樣的 就是後邊參數必須得是數組或者類數組,也就是說呀他傳進去以後會自動把這個數組或者類數組散開,和call好像啊!因此奧老二就介紹到這裏了 哈哈哈哈!

bind

介紹一下老幺吧

~~這三兄弟是否是三胞胎?bind的用法和call 如出一轍 只是否是讓函數當即執行的而是返回一個新函數,新函數執行時 ,裏邊的this 會改變成 指定的對象

看個小例子吧:

var fn2 = fn.bind(obj, 6, 6, 6)
    fn2()
複製代碼

讓fn執行而且把fn中的this 改爲了obj,還把6,6,6傳給了fn 就是呀新函數執行後他的this纔會變其餘和call是同樣滴

我們再封裝個本身的bind?

淦!來 !fn我們還用上邊的奧 就不寫了

Function.prototype.myBind = function (context, ...arg) {
        var _this = this 
        return function (...ary) {
             _this.call(context, ...arg)

        }
    }
複製代碼

注意奧var _this=this就是存儲的就是fn函數 其實呀就是讓call的返回值再加一步函數這樣就可讓他運行以後他再讓this指向我們第一項的參數了

還有一個簡單的方法:

Function.prototype.myBind=function(context,...arg){
            return(...ary)=>{
                this.call(context,...arg,...ary)
            }
        }
複製代碼

其實和上邊意思是同樣的 就是換成了箭頭函數this就本身找他去了

結尾

學會了吧?沒學會的話我要跑路的。不過apply 已經再找我麻煩了,拿着四十米的大刀追問我爲啥不給他封裝一個函數!!!

都看到這了還不三連?

相關文章
相關標籤/搜索