上次文章中提到了可以通过call,apply,bind修改函数的this指向,今天就来详细介绍一下。
1、call
- 作用:改变某个函数内部的this指向,指向到新的对象上
- 参数:参数1 新的this指向;后面的参数 被call的函数本身如果有形参,则按位置依次传入,如果没有则不传
- 场景:ES5构造函数 继承!
function fruit(a,b){
console.log('我最喜欢的水果是'+a+'和'+b);
console.log(this);
}
//1、遇到call之前,this指向的是window
fruit('苹果','香蕉') //分别打印:我喜欢的水果是苹果和香蕉,window
//2、经过call的调用,将fruit的this指向由window指向obj
var obj={name:'zs',age:18}
fruit.call(obj,'苹果','香蕉') //分别打印:我喜欢的水果是苹果和香蕉,obj
//将fruit函数的this指向修改为obj,并依次传入实参苹果和香蕉
2、apply
- 作用:改变this指向;遇见第一参数是谁就是谁!执行函数!
- 参数:参数1 新的this指向;执行函数传入的位置上数据!第二个参数数组 [位置上数据]
- 场景:遇见某个函数的参数是逗号分隔传入 -------------------------->数组形式;
function fruit(a,b){
console.log('我最喜欢的水果是'+a+'和'+b);
console.log(this);
}
//1、遇到apply之前,this指向的是window
fruit('苹果','香蕉') //分别打印:我喜欢的水果是苹果和香蕉,window
//2、经过apply的调用,将fruit的this指向由window指向obj
var obj={name:'zs',age:18}
fruit.apply(obj, ['苹果', '香蕉']) //分别打印:我喜欢的水果是苹果和香蕉,obj
//将fruit函数的this指向修改为obj,并传入参数数组 ['苹果', '香蕉']
3、bind
- 作用:把函数内部的this属性 全部指向我们定的一个对象!函数不执行!!!!
- 参数:参数1 新的this指向;后面的参数 被call的函数本身如果有形参,则按位置依次传入,如果没有则不传
- 场景:【函数,用外部的this改变函数内部this指向,用bind感染 fn.bind(新对象)】
function fruit(a, b) {
console.log('我最喜欢的水果是' + a + '和' + b);
console.log(this);
}
//1、遇到bind之前,this指向的是window
fruit('苹果', '香蕉') //分别打印:我喜欢的水果是苹果和香蕉,window
//2、经过bind的调用,将fruit的this指向由window指向obj
var obj = { name: 'zs', age: 18 }
fruit.bind(obj, '苹果', '香蕉')() //分别打印:我喜欢的水果是苹果和香蕉,obj
//将fruit函数的this指向修改为obj,并依次传入实参苹果和香蕉
总结一下这三种方法
- 相同点:都可以改变函数内部this指向
- 不同点:
- call 和 apply 会调用执行函数!bind 不会执行函数!
- 传递的参数不一样,call和bind传递参数使用逗号隔开,apply使用数组传递;
- 应用场景:
- call ES5构造函数的属性做继承.
- apply 参数形式 逗号形式---------------------->数组形式
var res = Math.max.apply(Math, [10, 10, 50, 99]) - bind 不执行函数, 只是想改变下函数内部this指向!我感染函数内部this指向;