這是一道今天遇到的面試題面試
由於setTimeout屬於匿名函數,this指向window,因此this.id = 1
但仍是先總結一下call和apply的用法。app
首先介紹一下call和apply的定義函數
obj.call(thisObj, arg1, arg2,...)
obj.apply(thisObj, [arg1, arg2,...])
call和apply的做用是改變函數運行時的上下文環境(改變this的指向),將obj綁定到thisObj,或者說this.Obj調用了obj裏面的方法。this
當一個對象須要調用另一個對象裏面的方法的時候,能夠用到call和apply,call和apply能夠理解成是繼承另一個對象的方法。spa
首先咱們創建兩個對象obj1和obj2code
若是obj2對象要調用obj1中的func1方法(能夠理解爲在obj2的環境中執行obj1.func1方法),則對象
obj1.func1.call(obj2); //輸出:obj2Name obj1.func1.apply(obj2);//輸出:obj2Name
call和apply第一個參數都是表示obj1綁定的對象,若是obj1要綁定到this,此時obj1就是綁定到全局,如:blog
obj1.func1.call(this);//輸出:windowName obj1.func1.apply(this);//輸出:windowName
若是obj2對象要調用obj1中的func2方法,則繼承
obj1.func2.call(obj2,1,2);//輸出:3 obj1.func2.apply(obj2,[1,2]);//輸出:3
使用call方法調用父構造函數ip
function Product(name, price) { this.name = name; this.price = price; if (price < 0) { throw RangeError( 'Cannot create product ' + this.name + ' with a negative price' ); } } function Food(name, price) { Product.call(this, name, price); this.category = 'food'; } //等同於 function Food(name, price) { this.name = name; this.price = price; if (price < 0) { throw RangeError( 'Cannot create product ' + this.name + ' with a negative price' ); } this.category = 'food'; } //function Toy 同上 function Toy(name, price) { Product.call(this, name, price); this.category = 'toy'; } var cheese = new Food('feta', 5); var fun = new Toy('robot', 40);
bind方法也是用來改變this的指向
var a = { user:"追夢子", fn:function(){ console.log(this.user); } } var b = a.fn; b.bind(a);
沒有被打印,這就是bind方法與apply、call方法的不一樣。bind方法返回的是修改事後的函數
var a = { user:"追夢子", fn:function(){ console.log(this.user); //追夢子 } } var b = a.fn; var c = b.bind(a); c();
執行成功