成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

dantezhao / 2305人閱讀

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

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

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

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

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

第一步

首先實現(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"}
第二步

第二步考慮傳參的問題,首先看看原生的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);

可以看出來在bind函數(shù)中能先傳部分參數(shù),運(yùn)行bind返回的函數(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來調(diào)用bind返回的函數(shù)時,會忽略bind傳入的this
new操作和普通的函數(shù)調(diào)用有哪些區(qū)別?
粗略的來講,例如new F()這樣的調(diào)用,有以下幾個步驟:

新建一個對象,var o = new Object()

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

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

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

開始實現(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操作的話,此時this的__proto__已經(jīng)指向了boundFunc,所以使用instanceof可以檢測出是否在使用new操作

小細(xì)節(jié)

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

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

可以看出來原型鏈丟失了,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;是因為這樣寫的話,修改boundFunc.prototype會影響到原函數(shù)的prototype。

that"all

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

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

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/108034.html

相關(guān)文章

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

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

    qpal 評論0 收藏0
  • Build your own AngularJS》筆記分享

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

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

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

    go4it 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<