1. 程式人生 > >【javascript】關於Function.prototype.bind

【javascript】關於Function.prototype.bind


我們知道 this 一般根據所處位置區分為兩種情況:

 

函式外面在全域性上下文下 指的是全域性物件

函式裡面的是函式上下文 (這個函式上下文有多種情況這裡不做描述)

 

也知道call 和 apply是可以改變函式內部的this物件。

最簡單的例子是這樣。

name = "kevin"

var o= {name: "kev"}

function ouputName () {

  console.log(this.name)

}

outputName(); //輸出的是 "kevin"

outputName.call(o); 
//輸入的是 "kev"

上面就是通過call方法改變this的值。普通的函式裡面的this,可以簡單的理解為誰呼叫這個函式,this物件就是誰。

這不是重點,重點是 還有一個方法 methos.bind(thisArg, [parames]). 

Function.prototype.bind

這個方法會返回一個和呼叫它的函式的同樣函式體和作用域的函式,並且只會生效一次。this物件會被永久繫結到第一個引數上面,後面多次改變this是無效的。

 

例子:

name = "kevin"

var o= {name: "kev"}

function ouputName () {   console.log(this.name) } outputName(); //輸出的是 "kevin" outputName.call(o); //輸入的是 "kev" //我們接著上面的例子來 var newO = {name: "Kesha"} var newFunc = outputName.bind(newO) //返回的函式和outputName是同樣的函式體, this物件是newO newFunc() //輸出的是 "Kesha" //重點是,這時候這個函式上下文永久的繫結到了newO物件上,this指向這個物件。 newFunc.call({name:
"Catherine"}) //輸出的仍然是"Kesha"

 

bind的特殊之處就是,返回函式的作用域永久的被繫結到了第一個引數上,後面用call, apply, bind都是不生效的。

 

那麼問題來了,這樣有什麼用?其實主要是函式宣告的時候是由我們決定的,但是函式執行的時候this 確實可以被動態修改的。這時候可能就需要bind函式固定this 上下文。

看例子:

    

var o = {

    name: 'kevin',

    sayHi: function() {    

         console.log('Hi. My name is '+ this.name)

    }

}

我們建立了一個物件,o,o.sayHi() 1秒中之後,輸出 'Hi, My name is kevin'


好,我們想時隔兩秒,再打招呼,程式碼這樣:

setTimeout(o.sayHi,  2000)

//oops 打印出來的是確是 Hi, My name is unidefined

sayHi函式丟失了this(obj)的繫結,而是繫結到了這個this(window物件),所以我們需要從新繫結this

setTimeout(o.sayHi.bind(o), 2000)