这是一道今天遇到的面试题
因为setTimeout属于匿名函数,this指向window,所以this.id = 1
但还是先总结一下call和apply的用法。
首先介绍一下call和apply的定义
obj.call(thisObj, arg1, arg2,...)
obj.apply(thisObj, [arg1, arg2,...])
call和apply的作用是改变函数运行时的上下文环境(改变this的指向),将obj绑定到thisObj,或者说this.Obj调用了obj里面的方法。
call和apply的作用
当一个对象需要调用另外一个对象里面的方法的时候,可以用到call和apply,call和apply可以理解成是继承另外一个对象的方法。
首先我们建立两个对象obj1和obj2
如果obj2对象要调用obj1中的func1方法(可以理解为在obj2的环境中执行obj1.func1方法),则
obj1.func1.call(obj2); //输出:obj2Name
obj1.func1.apply(obj2);//输出:obj2Name
call和apply第一个参数都是表示obj1绑定的对象,如果obj1要绑定到this,此时obj1就是绑定到全局,如:
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和apply实现继承
使用call方法调用父构造函数
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方法和call、apply的区别
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();
执行成功
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。