為何常常栽在call,apply,bind這些函數(shù)

1. call、apply、bind作用于函數(shù)上

2. call

<script type="text/javascript">
    var Dog = function () {
        this.name = "旺星人";
        this.shout = function () {
            alert(this.name);
        }
    };

    var Cat = function () {
        this.name = "喵星人";
    };

    var dog = new Dog();
    var cat = new Cat();
    dog.shout.call(cat); //dog.shout中的this對(duì)象,將指向cat對(duì)象。
    dog.shout();    //this還是指向dog 
</script>

3. apply

<script type="text/javascript">
    var xh = {
        name: "小紅",
        job: "JS工程師"
    };

    var xm = {
        name: "小明",
        job: "資深前端開發(fā)工程師"
    };

    var jx = {
        name: "杰西",
        job: "前端開發(fā)總監(jiān)"
    };

    //杰西,男,今年24歲,在前端開發(fā)網(wǎng)擔(dān)任前端開發(fā)總監(jiān)一職
    function myjob(gender, age, company) {
        alert(this.name + "," + gender + ",今年" + age + "歲,在" + company + "擔(dān)任" + this.job + "一職");
    }

    myjob.call(xh, "女", 22, "騰訊");
    myjob.call(xm, "男", 23, "谷歌");
    myjob.call(jx, "男", 24, "前端開發(fā)網(wǎng)");

    myjob.apply(xh, ["女", 22, "騰訊"]);
    myjob.apply(xm, ["男", 23, "谷歌"]);
    myjob.apply(jx, ["男", 24, "前端開發(fā)網(wǎng)"]);
</script>
總結(jié):
  • 在call傳入?yún)?shù)的時(shí)候,需要與函數(shù)所接受的參數(shù)一一對(duì)應(yīng);
  • 在apply傳入?yún)?shù)的時(shí)候,則以數(shù)組的方式傳入,數(shù)組中的元素需要與函數(shù)所接受的參數(shù)一一對(duì)應(yīng);
  • call、apply都是屬于立即調(diào)用

3.bind

  • MDN的解釋是:bind()方法會(huì)創(chuàng)建一個(gè)(新函數(shù)),稱為綁定函數(shù),當(dāng)調(diào)用這個(gè)綁定函數(shù)時(shí),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入 bind()方法的第一個(gè)參數(shù)作為 this,傳入 bind() 方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。
// 1.常用this賦值寫法
<script type="text/javascript">
    var foo = {
        bar: 1,
        eventBind: function () {
            var _this = this;
            $('.someClass').on('click', function (event) {
                /* Act on the event */
                console.log(_this.bar); //1
            });
        }
    }
</script>

// 2.bind()改變this指向
<script type="text/javascript">
    var foo = {
        bar: 1,
        eventBind: function () {
            $('.someClass').on('click', function (event) {
                /* Act on the event */
                console.log(this.bar); //1
            }.bind(this));
        }
    }
</script>
  • 直接使用對(duì)象屬性
<script type="text/javascript">

    var jx = {
        name: "杰西",
        gender: "男",
        age: 24,
        company: "前端開發(fā)網(wǎng)(W3Cfuns.com)",
        job: "前端開發(fā)總監(jiān)",
        say: function () {
            alert(this.name + "," + this.gender + ",今年" + this.age + "歲,在" + this.company + "擔(dān)任" + this.job + "一職");
        }
    };

    jx.say();

    var xm = jx.say.bind({
        name: "小明",
        gender: "男",
        age: 23,
        company: "谷歌 Google",
        job: "資深前端開發(fā)工程師"
    });
    xm();

    //注意:JavaScript1.8.5版本中,原生實(shí)現(xiàn)bind方法,目前IE9+,F(xiàn)F4,Chrome7+,opera
</script>
  • 重復(fù)使用bind會(huì)有什么效果
<script type="text/javascript">
    var bar = function () {
        console.log(this.x);
    }
    var foo = {
        x: 3
    }
    var sed = {
        x: 4
    }
    var func = bar.bind(foo).bind(sed);
    func(); //?

    var fiv = {
        x: 5
    }
    var func = bar.bind(foo).bind(sed).bind(fiv);
    func(); //?
</script>
  • 答案是,兩次都仍將輸出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是無效的。更深層次的原因, bind() 的實(shí)現(xiàn),相當(dāng)于使用函數(shù)在內(nèi)部包了一個(gè) call / apply ,第二次 bind() 相當(dāng)于再包住第一次 bind() ,故第二次以后的 bind 是無法生效的。

  • apply、call、bind比較

<script type="text/javascript">
    var obj = {
        x: 81,
    };

    var foo = {
        getX: function () {
            return this.x;
        }
    }

    console.log(foo.getX.bind(obj)()); //81
    console.log(foo.getX.call(obj)); //81
    console.log(foo.getX.apply(obj)); //81
</script>
  • 三個(gè)輸出的都是81,但是注意看使用 bind() 方法的,他后面多了對(duì)括號(hào)。
  • 也就是說,區(qū)別是,當(dāng)你希望改變上下文環(huán)境之后并非立即執(zhí)行,而是回調(diào)執(zhí)行的時(shí)候,使用 bind() 方法。而 apply/call 則會(huì)立即執(zhí)行函數(shù)。

再總結(jié)一下:

  • apply 、 call 、bind 三者都是用來改變函數(shù)的this對(duì)象的指向的;
  • apply 、 call 、bind 三者第一個(gè)參數(shù)都是this要指向的對(duì)象,也就是想指定的上下文;
  • apply 、 call 、bind 三者都可以利用后續(xù)參數(shù)傳參;
  • bind 是返回對(duì)應(yīng)函數(shù),便于稍后調(diào)用;apply 、call 則是立即調(diào)用 。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容