亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript bind函數(shù)手寫(xiě)教程

 更新時(shí)間:2022年12月19日 11:04:17   作者:helloworld1024fd  
bind()方法主要就是將函數(shù)綁定到某個(gè)對(duì)象,bind()會(huì)創(chuàng)建一個(gè)函數(shù),函數(shù)體內(nèi)的this對(duì)象的值會(huì)被綁定到傳入bind()第一個(gè)參數(shù)的值,當(dāng)然這是綁定哦,不是像call、apply一樣直接執(zhí)行,apply要執(zhí)行的話還得自己調(diào)用

經(jīng)常會(huì)看到網(wǎng)上各種手寫(xiě)bind的教程,下面是我在自己實(shí)現(xiàn)手寫(xiě)bind的過(guò)程中遇到的問(wèn)題與思考。如果對(duì)于如何實(shí)現(xiàn)一個(gè)手寫(xiě)bind還有疑惑的話,那么可以先看看上面兩篇文章。

手寫(xiě)bind vs 原生bind

我們先使用一個(gè)典型的手寫(xiě)bind的例子,代碼如下:

Function.prototype.bind2 = function (context) {
    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}

我們首先用原生bind運(yùn)行一下代碼

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind(undefined, 'a')
new _Foo() 

更多面試題解答參見(jiàn)前端手寫(xiě)面試題詳細(xì)解答

然后使用手寫(xiě)版代碼,運(yùn)行同樣的代碼

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind2(undefined, 'a')
new _Foo() 

我們可以看到相比原生bind方法,手寫(xiě)版的bind方法返回的構(gòu)造函數(shù),構(gòu)造出來(lái)的新對(duì)象會(huì)比原生的多一層__proto__。而這個(gè)__proto__產(chǎn)生的原因就是在很多教程中提到的防止原型鏈篡改。

這也就是為什么很多的文章會(huì)告訴你,為什么要添加下面的代碼。

var fNOP = function () {};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();

這段代碼中,使用了一個(gè)空函數(shù)作為中轉(zhuǎn),相當(dāng)于Object.create(fBound.prototype)。具體可以查看文章開(kāi)頭給出的文章,里面的詳細(xì)的說(shuō)明。

規(guī)范中的bind

既然說(shuō)道,加上面的代碼是為了防止原型鏈篡改。我就想看看原生的bind如何處理這個(gè)問(wèn)題的呢?

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind(undefined, 'a')
_Foo.prototype.sayHi = function( ) {console.log('篡改的_Foo的sayHi方法')}
(new _Foo().sayHi())

我發(fā)現(xiàn)在運(yùn)行上面的代碼,程序執(zhí)行到修改_Foo的原型方法的語(yǔ)句時(shí),就已經(jīng)報(bào)錯(cuò)了。提示表明_Foo沒(méi)有prototype屬性!既然沒(méi)有prototype屬性,那么是不是也就不用處理原型鏈篡改的問(wèn)題了呢?

之后,我查了一下規(guī)范, 在NOTE中,有下面一段話。明確指出了bind返回的函數(shù)是沒(méi)有prototype屬性,這也多少印證了上面的猜想。

Function objects created using Function.prototype.bind do not have a prototype property or the [[Code]], [[FormalParameters]], and [[Scope]] internal properties.

其中需要注意的有一點(diǎn)是這條:

Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1.

我自己理解的意思是是bind出來(lái)的函數(shù)對(duì)象的prototype屬性是內(nèi)建的Function.prototype屬性, 這里應(yīng)該是說(shuō)明了為什么原生的bind不會(huì)多一層__proto__屬性

小結(jié)

寫(xiě)這篇的目的是總結(jié)下自己在實(shí)現(xiàn)bind過(guò)程中遇到的問(wèn)題,記錄探究的過(guò)程。通過(guò)一系列手寫(xiě)原生方法,鍛煉了我們對(duì)于原理的進(jìn)一步認(rèn)識(shí)。但是也要注意驗(yàn)證,實(shí)際去操作幾次,可能得出自己的經(jīng)驗(yàn)。如果有更多的兩者對(duì)比的發(fā)現(xiàn),可以在評(píng)論里告訴我,歡迎各位大佬斧正。

到此這篇關(guān)于JavaScript bind函數(shù)手寫(xiě)教程的文章就介紹到這了,更多相關(guān)JS bind函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論