> For the complete documentation index, see [llms.txt](https://jen-hsuan-hsieh.gitbook.io/javascript-node-js/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jen-hsuan-hsieh.gitbook.io/javascript-node-js/chapter1/12javascript-quan-gong-lve-ff1a-ke-fu-js-de-qi-guai-bu-fen/123wu-jian-yu-han-shu/12321callapply-yu-bind.md).

# 1.2.3.21.call()、apply() 與 bind()

* [當執行環境被建立時會產生幾樣東西:](https://jenhsuan.gitbooks.io/javascript-node-js/content/chapter1/1238wu-jian-3001-han-shu-yu-300c-this.html)
  * 1.變數環境 (Variable environment), 外部環境 (Outer environment)
    * 當在變數環境找不到變數時, 會到所參照的外部環境去尋找
  * 2.this
    * 不須宣告, 由JavaScript engine產生, this依據函數的呼叫方式會指向不同的物件
  * 3.外部參照的環境
* [函數](https://jenhsuan.gitbooks.io/javascript-node-js/content/chapter1/1235han-shu-jiu-shi-wu-jian.html)除了CODE property與name property外, 預設會有call(), apply(), bind()&#x20;
  * 程式1的this會指向person, 因為是[物件本身的方法](https://jenhsuan.gitbooks.io/javascript-node-js/content/chapter1/1238wu-jian-3001-han-shu-yu-300c-this.html)
  * 程式2的this會指向全域物件
  * 程式3使用bind傳入this所想指向的物件, 並回傳一個新的函數
  * 程式5使用call傳入this所想指向的物件以及參數, 並執行函數
  * 程式6使用apply傳入this所想指向的物件以及參數, 並執行函數
  * 程式7使用[IIFE](https://jenhsuan.gitbooks.io/javascript-node-js/content/chapter1/12315li-ji-hu-jiao-dehan-shu-biao-shi-shi-ff08-iifes.html), apply傳入this所想指向的物件以及參數, 並執行函數
  * function borrowing
  * function currying
    * bind的第二個參數會作為新函數的第一個參數並永久使用
* function currying
  * 建立一個函數的拷貝並設定預設的參數
* bind: 將this重新指向, 創造函數的拷貝並返回但不會執行
* call: 將this重新指向並傳入其他參數, 並執行函數
* apply: 將this重新指向並傳入其他參數, 並執行函數

```
//程式碼1
var person = {
    firstname = 'John',
    lastname = 'Doe',
    getFullFunction: function (){
        var fullname = this.firstname + ' ' + this.lastname;
        return fullname;
    }
}

//程式碼2       
var logName = function(lang1, lang2){
    console.log('Logged: ' + this.getFullName())
}

//執行失敗
logName();

//程式碼3
var logPersonName = logName.bind(person)
logPersonName();

//程式碼4
var logName = function(lang1, lang2){
    console.log('Logged: ' + this.getFullName())
}.bind(person)

logName();

//程式碼5
var logName = function(lang1, lang2){
    console.log('Logged: ' + this.getFullName())
}

logName.call(person, 'en', 'es');

//程式碼6
logName.apply(person, ['en', 'es']);

//程式碼7
(function(lang1, lang2){
    console.log('Logged: ' + this.getFullName())
}).apply(person, ['en', 'es']);


//function borrowing
var person2 = {
    firstname = 'Jane',
    lastname = 'Doe'
}

console.log(person.getFullName.apply(person2));

//function currying
function multiply(a, b) {
    return a * b;
}

var multiplyByTwo = multiply(this, 2);
//印出8
console.log(multiplyByTwo(4));
```
