簡析JavaScript中的Function型別(五)——設定函式的作用域
阿新 • • 發佈:2019-04-07
在JavaScript中,函式執行時都具有特定的作用域,如下程式碼:
var name = 'Jack'; var person = { name: 'Bob', sayName: function(code, msg){ console.log(code, msg + this.name); } } person.sayName(0, 'hello ');// 0 "hello Bob" var newSay = person.sayName; newSay(0, 'hello ');// 0 "hello Jack"
先宣告一個name
變數,然後宣告一個person
物件,person
包含name
和sayName
屬性。當直接在物件上進行方法的呼叫時:person.sayName()
,函式的作用域遵循“誰呼叫就是誰”的原則,sayName
的作用域(也就是this
)指向的就是person
。
當把person.sayName
賦值給新變數newSay
時,呼叫newSay()
為直接的函式呼叫,此時函式的作用域變為了window
。本質上來講,newSay()
相當於window.newSay()
,所以同樣也是遵循“誰呼叫就是誰”的原則。
但是函式有三個方法可以用來設定作用域,分別為apply
、call
、bind
。
還是上面的例子,使用如下方式呼叫:
person.sayName.apply(window, [0, 'hello ']);//0 "hello Jack"
apply
接收兩個引數,第一個引數為函式執行時的作用域,也就是this
的值,這樣就可以人為的改變函式執行時的作用域了。
使用call
方法也是一樣:
person.sayName.call(window, 0, 'hello ');//0 "hello Jack"
區別在於apply
接收一個數組用於函式的引數,而call
需要把引數一一列出。
對於bind
,來看下面的程式碼:
var newSay2 = person.sayName.bind(person); newSay2(0, 'hello');//0 "hello Bob" console.log(person.sayName === newSay);// true console.log(person.sayName === newSay2);// false
bind
也是改變了作用域,但bind
建立了一個新的函式,這個函式具有和原函式相同的程式碼體。而apply
和call
都是