这是一道今天遇到的面试题面试
由于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();
执行成功