1,call()和apply()方法
都是用来改变this的指向
apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。它们都接受两个参数,一个是在其中运行的函数作用域,另一个是参数数组,其中第二个参数可是Array实例,也可以是arguments对象。参数可以是任意类型,当第一个参数为null,undefined的时候,默认指向window;
基本用法: A.call(B, args1,args2);即B对象调用A对象的方法
C.apply(D, [arg1,arg2])或arguments;即D对象应用C对象的方法
<script>
function sum(num1,num2){
return num1+num2
}
function callSum1(num1,num2) {
return sum.apply(this,arguments)
}
function callSum2(num1,num2) {
return sum.apply(this,[num1,num2])//传入数组
}
console.log(callSum1(1,2))//3
console.log(callSum2(3,4))//7
</script>
callSum1()在执行sum()函数时传入了this作为this值(因为在全局作用域中调用的,所以传入的就是window对象)和arguments对象。而callSum2同样也调用了sum()函数,但它传入的则是this和一个参数数组。这两个函数返回的结果相同。
call()和apply()方法的作用相同,它们的区别仅仅是接受参数的方式不同,对于call()方法,第一个参数是this值,变化的是其余参数都是直接传递给函数,也就是说在使用call()方法时,传递给函数的参数必须一个一个的列举出来。
<script>
function sum(num1,num2){
return num1+num2
}
function callSum1(num1,num2) {
return sum.call(this,num1,num2)
}
console.log(callSum1(1,2))//3
</script>
call()和apply()它们的作用一样,如果你打算直接传入arguments对象,或者包含函数中先接收到的也是一个数组,那么使用apply()方便,单个传入使用call()方法更合适。
注意:传递参数并且call()和apply()真正的用武之地,它们真正强大的地主是能够扩充函数运行的作用域。
<script>
window.color="red"
let o={color:"blue"}
function sayColor() {
console.log(this.color)
}
sayColor()
sayColor.call(this)//red
sayColor.call(window)//red
sayColor.call(o)//blue
</script>
这里sayColor()也是作为全局函数定义的,而且当在全局作用域中调用它时,它会显示"red",因为对this.color的求值会转换成对window.color的求值。而sayColor.call(this)和sayColor.call(window),则是两种显式地在全局作用域中调用函数的方式,结果当然会显示"red"。但是当运行sayColor.call(o)时,函数的执行环境不一样了,因为此时函数体内的this对象指向了o,于是结果就显示的是blue。
使用call()和apply来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
2,bind()方法
这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
<script>
window.color="red"
let o={color:"blue"}
function sayColor() {
console.log(this.color)//blue
return this.color
}
let obj=sayColor.bind(o)
console.log(obj())//blur
</script>
这里,sayColor()调用bind()并传入对象o,创建了obj函数,obj函数的this值等于o。
注意:bind()改过this后,不执行函数,会返回新的绑定this的函数。