国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【build your own xxx】實(shí)現(xiàn)你自己的bind函數(shù)

dantezhao / 2244人閱讀

今天來(lái)實(shí)現(xiàn)JavaScript的bind函數(shù)。
首先看MDN的bind函數(shù)描述:

從上面可以看出來(lái),var A = B.bind(this)函數(shù)其實(shí)干了這幾件事情:

返回一個(gè)函數(shù),且這個(gè)函數(shù)后面運(yùn)行時(shí)的this就是bind(this)傳入的this

接收參數(shù),這些參數(shù)(如果有的話)作為bind()的第二個(gè)參數(shù)跟在this(或其他對(duì)象)后面,之后它們會(huì)被插入到目標(biāo)函數(shù)的參數(shù)列表的開(kāi)始位置,傳遞給綁定函數(shù)的參數(shù)會(huì)跟在它們的后面

使用new操作bind函數(shù)返回的函數(shù)時(shí),之前傳入的this會(huì)被忽略,也就是說(shuō)new的優(yōu)先級(jí)高于bind

第一步

首先實(shí)現(xiàn)第一步:

Function.prototype.Zbind = function (othis) {
    var originFunc = this;
    return function () {
        originFunc.apply(othis);
    }
}


var obj = {

}

function createAgumon() {
    this.name = "agumon";
}
var createAgumonBind = createAgumon.Zbind(obj);
createAgumonBind();   
obj;// {name: "agumon"}
第二步

第二步考慮傳參的問(wèn)題,首先看看原生的bind函數(shù)是如何傳參的:

var obj = {

}
function createAgumon(gender, age) {
    this.name = "agumon";
    this.gender = gender;
    this.age = age;
}
var createAgumonBind = createAgumon.bind(obj, "female");
createAgumonBind(22);

可以看出來(lái)在bind函數(shù)中能先傳部分參數(shù),運(yùn)行bind返回的函數(shù)時(shí)可以再傳入部分參數(shù)。
自己實(shí)現(xiàn):

Function.prototype.Zbind = function (othis) {
    var originFunc = this;
    var partArgs = [].slice.call(arguments, 1);
    var func = function() {};
    var boundFunc = function () {
        var finalArgs = partArgs.concat([].slice.call(arguments));
        return originFunc.apply(othis, finalArgs);
    }

    return boundFunc;
}


var obj = {

}

function createAgumon(gender, age) {
    this.name = "agumon";
    this.gender = gender;
    this.age = age;
}

var createAgumonBind = createAgumon.Zbind(obj, "female");
createAgumonBind(22);
obj;// {name: "agumon", gender: "female", age: 22}
第三步

使用new來(lái)調(diào)用bind返回的函數(shù)時(shí),會(huì)忽略bind傳入的this
new操作和普通的函數(shù)調(diào)用有哪些區(qū)別?
粗略的來(lái)講,例如new F()這樣的調(diào)用,有以下幾個(gè)步驟:

新建一個(gè)對(duì)象,var o = new Object()

設(shè)置原型鏈,o.__proto__ = F.prototype

把F函數(shù)體內(nèi)的this綁定為o,并且執(zhí)行F函數(shù)的代碼

判斷F的返回類型:
如果是值類型,則返回o
如果是引用類型,則返回該引用類型對(duì)象

開(kāi)始實(shí)現(xiàn):

Function.prototype.Zbind = function (othis) {
    var originFunc = this;
    var partArgs = [].slice.call(arguments, 1);
    var func = function() {};
    var boundFunc = function () {
        var finalArgs = partArgs.concat([].slice.call(arguments));
        return originFunc.apply(this instanceof boundFunc ? this : othis, finalArgs);
    }


    return boundFunc;
}


var obj = {}

function createAgumon(gender, age) {
        this.name = "agumon";
        this.gender = gender;
        this.age = age;
}

var createAgumonBind = createAgumon.Zbind(obj, "female");
var newObj = new createAgumonBind(22);
obj // {}
newObj // {name: "agumon", gender: "female", age: 22}

關(guān)鍵的地方在于這里:this instanceof boundFunc ? this : othis,如果是new操作的話,此時(shí)this的__proto__已經(jīng)指向了boundFunc,所以使用instanceof可以檢測(cè)出是否在使用new操作

小細(xì)節(jié)

原型丟失
剛剛實(shí)現(xiàn)的Zbind方法有個(gè)小問(wèn)題:

Function.prototype.Zbind = function (othis) {
            var originFunc = this;
            var partArgs = [].slice.call(arguments, 1);
            var func = function() {};
            var boundFunc = function () {
                var finalArgs = partArgs.concat([].slice.call(arguments));
                return originFunc.apply(this instanceof boundFunc ? this : othis, finalArgs);
            }


            return boundFunc;
        }


        var obj = {

        }

        function createAgumon(gender, age) {
            this.name = "agumon";
            this.gender = gender;
            this.age = age;
        }
        createAgumon.prototype.college = "THU"
        var createAgumonBind = createAgumon.Zbind(obj, "female");
        var newObj = new createAgumonBind(22);
        console.log(newObj.college)// undefined

可以看出來(lái)原型鏈丟失了,newObj.college得是"THU"才行

修改:

Function.prototype.Zbind = function (othis) {
            var originFunc = this;
            var partArgs = [].slice.call(arguments, 1);
            var func = function() {};
            var boundFunc = function () {
                var finalArgs = partArgs.concat([].slice.call(arguments));
                return originFunc.apply(this instanceof boundFunc ? this : othis, finalArgs);
            }

            func.prototype = originFunc.prototype;
            boundFunc.prototype = new func();

            return boundFunc;
        }


        var obj = {

        }

        function createAgumon(gender, age) {
            this.name = "agumon";
            this.gender = gender;
            this.age = age;
        }
        createAgumon.prototype.college = "THU"
        var createAgumonBind = createAgumon.Zbind(obj, "female");
        var newObj = new createAgumonBind(22);
        console.log(newObj.college)// "THU"

為什么要使用func.prototype = originFunc.prototype;boundFunc.prototype = new func();,而不是直接用boundFunc.prototype = originFunc.prototype;是因?yàn)檫@樣寫的話,修改boundFunc.prototype會(huì)影響到原函數(shù)的prototype。

that"all

參考資料:
mdn-bind
javascript中,new操作符的工作原理是什么?

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/108034.html

相關(guān)文章

  • build your own xxx實(shí)現(xiàn)自己call和apply

    摘要:新開(kāi)一個(gè)坑,起名為,自己造一些小輪子。之前貌似在知乎上看到一個(gè)問(wèn)題是說(shuō)如何使用實(shí)現(xiàn)它原生的和方法,今天我來(lái)實(shí)現(xiàn)一番。但是,這樣等于說(shuō)只給傳了一個(gè)數(shù)組參數(shù),并不能達(dá)到目的。同理來(lái)實(shí)現(xiàn)參考資料深入之和的模擬實(shí)現(xiàn) showImg(https://segmentfault.com/img/bVbbHCv?w=1123&h=629); 新開(kāi)一個(gè)坑,起名為【build your xxx】,自己造一...

    qpal 評(píng)論0 收藏0
  • Build your own AngularJS》筆記分享

    摘要:初次寫文章,請(qǐng)多多包涵我最近正在根據(jù)這本書從頭開(kāi)始實(shí)現(xiàn)了一遍的框架。筆記目錄鏈接個(gè)人認(rèn)為本書對(duì)于想了解框架源碼的讀者來(lái)說(shuō)相當(dāng)有用,完全值得去購(gòu)買這本書書本主頁(yè)。因?yàn)槭浅鯇W(xué)者,筆記里可能有一些錯(cuò)誤,我也會(huì)繼續(xù)修改。 (初次寫文章,請(qǐng)多多包涵) 我最近正在根據(jù)《Build your own angularJS》這本書從頭開(kāi)始實(shí)現(xiàn)了一遍AngularJS的框架。我把相關(guān)的源碼和我的個(gè)人學(xué)習(xí)筆...

    firim 評(píng)論0 收藏0
  • Spring Boot (一)helloworld

    摘要:第二個(gè)類級(jí)別注解是。將引導(dǎo)應(yīng)用程序,啟動(dòng),從而啟動(dòng)自動(dòng)配置服務(wù)器。比如想使用不同版本的,具體如下在標(biāo)簽中還可以指定編譯的版本和項(xiàng)目的編碼格式指定項(xiàng)目編碼為使用插件可以為項(xiàng)目提供的操作方式,的個(gè),默認(rèn)。 引言 Spring 框架對(duì)于很多 Java 開(kāi)發(fā)人員來(lái)說(shuō)都不陌生。Spring 框架包含幾十個(gè)不同的子項(xiàng)目,涵蓋應(yīng)用開(kāi)發(fā)的不同方面。如此多的子項(xiàng)目和組件,一方面方便了開(kāi)發(fā)人員的使用,另外...

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

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

0條評(píng)論

閱讀需要支付1元查看
<