1. 三者的共同点
- 三者调用目的都是改变调用对象的this指向
- 第一个参数都是this要指向的对象,第二个参数以及后面参数都是需要传入的参数
举个栗子:
function apple(){}
apple.prototype = {
color:"red",
showAppleColor:function(){
console.log(this.color)
}
}
var appleInstance = new apple;
这里定义了一个apple的类,定义了一个属性,一个方法。假如现在有一个对象,但是这个对象没有showAppleColor这个方法,如果想调用这个方法怎么办?这里就用到了call、apply、bind。
//现在有一个对象
var banana = {
color:"yellow"
}
//使用call
appleInstance.showAppleColor.call(banana) // result : yellow
//使用apply
appleInstance.showAppleColor.apply(banana) //result : yellow
//使用bind
appleInstance.showAppleColor.bind(banana)() //result : yellow
解释:因为banana没有这个方法,但是appleInstance有,所以banana可以使用call apply bind借用这个方法,但是this指向仍然指向banana这个对象,这样就可以不用单独创建这个方法。
这样的好处是很多方法我都可以借用已有的。eg : 找出数组[1,2,3,4,5]中的最大值
Math.max.apply([1,2,3,4,5])
2. 三者的不同点
- call和apply的不同点在于,传的参数不同,call是直接将参数传输进去,apply是需要将参数变为数组在传进去。
// eg :数组取最大值的例子
// 一般写法
Math.max(1,2,3,4,5) // result : 5
// 使用call的写法
Math.max.call(null,1,2,3,4,5)
// 使用apply的写法
Math.max.apply(null,[1,2,3,4,5])
// 使用bind的写法
Math.max.bind(null,1,2,3,4,5)()
可以看到,第一个参数都是你需要this指向的对象,如果是自身可以不定义(可以使用this,null,undefined),从第二个参数开始都是需要传入的参数。
使用call,bind,参数需要列在后面
使用apply,参数需要以数组的形式传进去
- bind只是绑定了一个对象,如果需要执行方法,后面还要加括号来执行
function calculate(b){
this.a = 10
console.log(this.a + b)
}
var example = {a:20}
var v = calculate.bind(example,10)
v() // result : 30
优点就是可以颗粒化参数,可以在自己想要执行的时候再执行
举个栗子:
function calculate(a,b,c,d){
console.log(a+b+c+d)
}
var v = calculate.bind(null,1,2,3)
var v1 = v(4) // 10
var v2 = v(5) // 11
var v3 = v(6) // 12
3. 常用的一些
- 判断数组
function isArray(arr){
return Object.prototype.toString.call(arr) === '[object Array]'
}
- 参数或者伪数组的拆分
var domArrays = Array.prototype.slice.call(document.getElementByTagName('div'))
var args = Array.prototype.slice.call(arguments)
- (面试题)自定义一个log,实现console.log的方法
function log(){
console.log.apply(null , arguments)
}
// 如果想在参数前加一个(test)
function log(){
var args = Array.prototype.slice.call(arguments)
args.unshift('(test)')
console.log.apply(null,args)
}
网友评论