簡析JavaScript中的Function類型(五)——設置函數的做用域

在JavaScript中,函數運行時都具備特定的做用域,以下代碼: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包含namesayName屬性。當直接在對象上進行方法的調用時:person.sayName(),函數的做用域遵循「誰調用就是誰」的原則,sayName的做用域(也就是this)指向的就是personjava

當把person.sayName賦值給新變量newSay時,調用newSay()爲直接的函數調用,此時函數的做用域變爲了window。本質上來說,newSay()至關於window.newSay(),因此一樣也是遵循「誰調用就是誰」的原則。數組

可是函數有三個方法能夠用來設置做用域,分別爲applycallbindapp

仍是上面的例子,使用以下方式調用:函數

person.sayName.apply(window, [0, 'hello ']);//0 "hello Jack"

apply接收兩個參數,第一個參數爲函數運行時的做用域,也就是this的值,這樣就能夠人爲的改變函數運行時的做用域了。this

使用call方法也是同樣:code

person.sayName.call(window, 0, 'hello ');//0 "hello Jack"

區別在於apply接收一個數組用於函數的參數,而call須要把參數一一列出。對象

對於bind,來看下面的代碼:ip

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建立了一個新的函數,這個函數具備和原函數相同的代碼體。而applycall都是調用的原函數。作用域

相關文章
相關標籤/搜索