JavaScript主要是一門面向對象的語言,對象是JavaScript的核心,函數是一種特殊的對象。其中,函數作為對象,具有調用和被調用兩種行為。其中被調用的方式有很多種,比如直接調用、apply調用、call調用,以及bind綁定等,本文主要介紹bind綁定的原理。
舉個例子,我們現在有一個對象person,以及一個sayHello方法,我們可以使用如下語句進行調用:
var person = { name: "lucy", sayHello: function () { console.log('Hello, ' + this.name + '!'); } }; person.sayHello(); // Hello, lucy!
那么現在我們來調用sayHello方法,但是要改變其中this的指向,讓其指向某一個不同的對象。這個時候,我們可以使用bind方法實現:
var anotherPerson = { name: "bob" }; var sayHelloToBob = person.sayHello.bind(anotherPerson); sayHelloToBob(); // Hello, bob!
在上述代碼中,我們使用bind方法將person對象的sayHello方法綁定到了anotherPerson對象上,這樣我們調用sayHelloToBob方法時,實際上this指向了anotherPerson對象。
那么,bind綁定的原理是什么呢?每個函數都有一個call方法和一個apply方法,它們都可以用來改變函數中this的指向。但是,call方法和apply方法不會改變原函數,而是生成了一個新的函數并立即調用,而bind方法則會返回一個新的函數,必須手動調用才能執行。
看下面的例子:
var name = "global name"; function sayName() { console.log(this.name); } var obj = { name: "obj name" }; sayName.call(obj); // obj name sayName.apply(obj); // obj name var objSayName = sayName.bind(obj); objSayName(); // obj name
在上述代碼中,我們定義了一個函數sayName,并同時定義了一個變量name。接著我們使用call方法和apply方法,來改變sayName函數中this的指向,從而輸出了obj對象中的name屬性。
最后,我們使用bind方法將sayName函數綁定到obj對象上,并將其賦值給了objSayName變量。當我們調用objSayName時,sayName函數內部的實際this仍然指向obj對象,從而輸出了obj對象中的name屬性。
綜上所述,bind方法的主要原理就是在調用時會返回一個新的函數,并將原函數中的this指向修改成綁定對象。由于返回的是函數而不是立即執行,我們可以隨時調用新函數,以達到需要的效果。