摘要:會(huì)創(chuàng)建一個(gè)新的函數(shù),成為綁定函數(shù),目標(biāo)函數(shù)和綁定函數(shù)有共同的函數(shù)體。新的目標(biāo)函數(shù)被調(diào)用的時(shí)候,就會(huì)綁定到函數(shù)的第一個(gè)參數(shù)上,且該參數(shù)不能被重寫。當(dāng)新的目標(biāo)函數(shù)被創(chuàng)建的時(shí)候,目標(biāo)函數(shù)的的值通過(guò)被設(shè)成了傳入的參數(shù)的值。
bind 概述
bind方法是綁定在了Function.prototype上。這個(gè)方法會(huì)創(chuàng)建一個(gè)新的函數(shù),當(dāng)被調(diào)用時(shí),會(huì)將其this關(guān)鍵字,設(shè)置為一個(gè)提供的值。
bind()會(huì)創(chuàng)建一個(gè)新的函數(shù),成為綁定函數(shù),目標(biāo)函數(shù)和綁定函數(shù)有共同的函數(shù)體。新的目標(biāo)函數(shù)被調(diào)用的時(shí)候,this就會(huì)綁定到bind()函數(shù)的第一個(gè)參數(shù)上,且該參數(shù)不能被重寫。在函數(shù)調(diào)用的時(shí)候,也可以為目標(biāo)函數(shù)增加新的參數(shù),參數(shù)跟在第一個(gè)參數(shù)之后。
bind綁定this指向var a = "hello 222" var obj = { "a":"hello 111", say:function(){ return this.a } } var otherSay = obj.say console.log(obj.say()) //hello 111 console.log(otherSay()) //hello 222
我們都知道,this的指向取決于函數(shù)的調(diào)用而不是生命的位置,所以,otherSay()被調(diào)用的this指向全局對(duì)象,這時(shí)候a并不是obj里邊定義的。所以會(huì)輸出"hello 222"。
我們可以使用bind來(lái)改變otherSay()的this指向。當(dāng)然call和apply也能做到。但是bind和另外兩個(gè)方法是不一樣的。
var newSay = otherSay.bind(obj) console.log(newSay())
綁定函數(shù)newSay(),目標(biāo)函數(shù)otherSay().用bind執(zhí)行完操作后,兩個(gè)函數(shù)共用同樣一個(gè)執(zhí)行環(huán)境,不管怎么調(diào)用,兩個(gè)函數(shù)都有同樣的this值。
背后的實(shí)現(xiàn)bind是綁定在了Function的原型上。它是ES5提出來(lái)的,用了ES3的apply作為背后的實(shí)現(xiàn)。
Function.prototype.bind = function(obj){ var _self = this return function(){ return _self.apply(obj) } }
當(dāng)新的目標(biāo)函數(shù)被創(chuàng)建的時(shí)候,目標(biāo)函數(shù)的this的值通過(guò)apply被設(shè)成了傳入的參數(shù)的值。因?yàn)椋覀儌魅胛覀兿胍暮瘮?shù)上下文,當(dāng)函數(shù)調(diào)用的時(shí)候this就會(huì)指向了第一個(gè)參數(shù)。
函數(shù)柯里化函數(shù)柯里化的概念是只傳給函數(shù)一部分參數(shù)就能調(diào)用他,讓他返回一個(gè)新的函數(shù)去處理另外的參數(shù)。
function add(x){ return function(y){ return x+y } } var add1 = add(10) add1(20) //30 add1(-10) // 0
用bind()可以實(shí)現(xiàn)函數(shù)的柯里化
function gender,age,name){ var salutation = gender === “male” ? “Mr” : "Ms" if(age > 25){ return "hello" + salutation + name } else{ return "hey" + name } }
這是一個(gè)很簡(jiǎn)單的函數(shù),很好理解。
接下來(lái),我們使用柯里化greet()方法.bind()接收的第一個(gè)參數(shù)指定的this的值。
var greetMaleAdult = greet.bind(null,"name",44) greetMaleAdult("Peter") var greetChild = greet(null,"",12) greetChild("Bob")
使用bind函數(shù),可以將greet函數(shù)柯里化,我們只需要指定最后一個(gè)參數(shù)來(lái)執(zhí)行柯里化之后的新函數(shù),因?yàn)榍斑厓蓚€(gè)參數(shù),d都在greet里邊定義好了。
apply和call 概述這兩個(gè)方法放在一起將,因?yàn)閮蓚€(gè)函數(shù)基本上沒(méi)有區(qū)別。
兩個(gè)函數(shù)都是寫到了Function.prototype上面。本質(zhì)上這兩個(gè)方法可以幫助我們實(shí)現(xiàn)函數(shù)借用和指定函數(shù)的this值。apply()允許我們傳入一個(gè)參數(shù)數(shù)組來(lái)傳給函數(shù),供這個(gè)函數(shù)使用。
當(dāng)我們使用這兩個(gè)函數(shù)的時(shí)候,傳入的第一個(gè)參數(shù)作為this的目標(biāo)指向。
var age = 11 function showAge(){ console.log(this.age) } var Man = { age:15 } showAge.apply(Man) // 立即返回15
我們看到,加了一行代碼,我們改變了showAge中的this指向,開(kāi)始的時(shí)候,全局函數(shù)showAge中的指向是全局對(duì)象,但是,我們通過(guò)apply函數(shù),把this指向了一個(gè)對(duì)象Man,這個(gè)時(shí)候,會(huì)立即返回函數(shù)的執(zhí)行結(jié)果15
apply和bind不一樣的地方在于,bind不會(huì)立即返回結(jié)果,會(huì)返回一個(gè)新的函數(shù),我們調(diào)用這個(gè)函數(shù),才會(huì)返回結(jié)果
var age = 11 function showAge(){ console.log(this.age) } var Man = { age:15 } showAge.bind(Man) // 并不會(huì)立即執(zhí)行 showAge.bind(Man)() // 執(zhí)行返回的函數(shù),顯示15
另外,在回調(diào)函數(shù)中,我們也可以通過(guò)apply或者call方法手動(dòng)設(shè)置this的指向。
var obj = { fullname:"not set", showName:function(firstname,lastname){ this.fullname = firstname + " " +lastname } } function getFullname(firstname,lastname,callback,callbackobj){ callback.call(callbackobj,firstname,lastname) } getFullname("zhang","heihei",obj.showName,obj) console.log(obj.fullname) // zhang heihei函數(shù)借用
call和apply的存在可以讓我們借用其他對(duì)象的函數(shù)來(lái)處理。最典型的例子就是我們可以通過(guò)函數(shù)借用來(lái)讓類數(shù)組對(duì)象使用數(shù)據(jù)的方法。
var arrayLikeObj = { "0":"haha", "1":1, "2":true, "3":[1,2,3], length:4 } var newArr = Array.prototype.slice.call(arrayLikeObj,0) // ["haha",1,true,Array[3]] var index = Array.prototype.indexOf.apply(arrayLikeObj,1) //1
這樣操作的好處就是既可以保留對(duì)象上的那些屬性,又可以隨時(shí)使用數(shù)組的方法。
總結(jié)三個(gè)函數(shù)的最大區(qū)別在于:bind函數(shù)是返回一個(gè)函數(shù)(內(nèi)部實(shí)現(xiàn)也是用的apply)供后續(xù)調(diào)用,而call和apply是立即調(diào)用返回執(zhí)行結(jié)果。
另外,在箭頭函數(shù)中,apply和call會(huì)失效,因?yàn)椋^函數(shù)的this是確定的,是所在的執(zhí)行上下文,而不是調(diào)用的時(shí)候的函數(shù)使用者。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93142.html
摘要:的調(diào)用者,將會(huì)指向這個(gè)對(duì)象。此外,還可以擴(kuò)展自己的其他方法。的使用最后來(lái)說(shuō)說(shuō)。不同的是,方法的返回值是函數(shù),并且需要稍后調(diào)用,才會(huì)執(zhí)行。而和則是立即調(diào)用。總結(jié)和的主要作用,是改變對(duì)象的執(zhí)行上下文,并且是立即執(zhí)行的。 前言 上一篇文章 《「前端面試題系列4」this 的原理以及用法》 中,提到了 call 和 apply。 它們最主要的作用,是改變 this 的指向。在平時(shí)的工作中,除了...
摘要:我是前端我的全名是我是一個(gè)前端指向接收多個(gè)參數(shù),第一個(gè)是返回值返回值是一個(gè)函數(shù)上下文的,不會(huì)立即執(zhí)行。柯里化相關(guān)講解請(qǐng)移步簡(jiǎn)版的實(shí)現(xiàn)就算完成了歡迎吐槽點(diǎn)贊 它們有什么不同?怎么用? call 接收多個(gè)參數(shù),第一個(gè)為函數(shù)上下文也就是this,后邊參數(shù)為函數(shù)本身的參數(shù)。 let obj = { name: 一個(gè) } ...
摘要:在傳統(tǒng)的面向類的語(yǔ)言中,構(gòu)造函數(shù)是類中的一些特殊方法,使用初始化類是會(huì)調(diào)用類中的構(gòu)造函數(shù)。 在上一節(jié)中我們?cè)敿?xì)介紹了this的兩種綁定方式,默認(rèn)綁定和隱式綁定,在這一節(jié)我們繼續(xù)介紹this的另外兩種綁定方式顯示綁定和new綁定。那么,我們要解決的問(wèn)題當(dāng)然就是上一節(jié)中我們提到的:this丟失! 顯式綁定 在隱式綁定中,我們必須在一個(gè)對(duì)象的內(nèi)部包含一個(gè)指向函數(shù)的屬性,并通過(guò)這個(gè)屬性間接引用...
摘要:什么是函數(shù)引用的原話函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語(yǔ)句。函數(shù)是由這樣的方式進(jìn)行聲明的關(guān)鍵字函數(shù)名一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。 什么是函數(shù)? 引用 W3School 的原話: 函數(shù)是一組可以隨時(shí)隨地運(yùn)行的語(yǔ)句。 函數(shù)是 ECMAScript 的核心。 函數(shù)是由這樣的方式進(jìn)行聲明的:關(guān)鍵字 function、函數(shù)名、一組參數(shù),以及置于括號(hào)中的待執(zhí)行代碼。 函數(shù)的基本語(yǔ)法是這樣的:...
摘要:與其他編程語(yǔ)言相比,對(duì)的使用是一套完全不同的機(jī)制。在五種情況下的值是各有不同的。調(diào)用一個(gè)函數(shù)時(shí)在這里,同樣指向全局對(duì)象。此時(shí)在函數(shù)內(nèi),指向新建的對(duì)象。盡管,晚綁定初看上去是個(gè)不好的決定,但實(shí)際上這是原型式繼承工作的基礎(chǔ)。 與其他編程語(yǔ)言相比,Javascript 對(duì) this 的使用是一套完全不同的機(jī)制。this 在五種情況下的值是各有不同的。 全局作用域下 this; 當(dāng)在全...
閱讀 885·2021-10-13 09:39
閱讀 3535·2021-09-26 10:16
閱讀 2874·2019-08-30 15:54
閱讀 1051·2019-08-30 14:22
閱讀 2894·2019-08-29 15:39
閱讀 3260·2019-08-27 10:52
閱讀 816·2019-08-26 13:59
閱讀 1711·2019-08-26 12:20