在不同类型的函数中this的指向是不同的。eg:
有的时候我们可能需要改变this的指向,通常使用call()、apply()、bind()三种方式。
1.call():
使用方式:被调函数名.call(param1,param2,param3,…);
param1: 函数运行中指定的this值;
param2,param3,…: 函数中传入的参数;
通常使用call()解决构造函数中的继承问题:令son的原型对象指向father的实例对象;
<script>
//借用父构造函数继承属性
//1.父构造函数
function Father(uname,age){
//this指向父构造函数的对象实例
this.uname = uname;
this.age =age;
}
//2.子构造函数
function Son(uname,age){
//this指向子构造函数的对象实例
Father.call(this,uname,age);
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题,如果改变了子原型对象,父原型对象也会一起变化
Son.prototype = new Father();
//如果使用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数。
Son.prototype.constructor = Son;
var son = new Son('xiaozhan','18');
console.log(son);
console.log(Father);
</script>
2. apply() :
使用方式:被调函数名.apply(param1, param2);
param1: 函数运行中指定的this值;
param2:这个参数必须为数组或者类数组(arguments对象);
通常使用apply()求数组中的最大最小值调用Math方法
var arr = [1,2,6,23,21];
var max = Math.max.apply(Math,arr);//建议apply()第一个参数改为调用者Math,更加直观,写成null也不会报错;
console.log(max);
那么为什么不直接使用math.max()呢?
这是因为,math.max(param1,param1,…)中的参数只能为Number类型的参数,如果我们放一个数组在里面将会报错:
math.max([1,2,6,23,21]); //math is not defined
而apply会将数组中的参数内容一个接一个的传递给方法,也就是说,apply()会将数组里面参数的内容取出,从而可以让math.max可以直接使用,这样 就得到了数组中的最值。
我们要想直接使用math.max(),可采用如下方法:
console.log(Math.max(1,2,6,23,21));
3.bind():
使用方式:被调函数名.bind(param1, param2,paean2,…);
·param1: 函数运行中指定的this值;
·param2,param3,…: 传递的其他参数。
·返回由指定的this值和初始化参数改造的原函数拷贝
使用的时候需要手动调用下返回 的新函数(不会自动执行)
由于bind()不调用函数,通常使用bind()改变定时器内部的this指向。
eg:使得用户点击按钮禁用两秒后恢复正常:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bind()</title>
</head>
<body>
<button>点击按钮禁用两秒后恢复正常</button>
<button>点击按钮禁用两秒后恢复正常</button>
<button>点击按钮禁用两秒后恢复正常</button>
</body>
<script>
var btns = document.querySelectorAll('button');
for(var i = 0; i < btns.length; i++){
btns[i].onclick = function(){
this.disabled = true;
setTimeout(function(){
this.disabled = false;
}.bind(this),2000);//bind()在定时器的外部,指向的是点击的按钮对象。
}
}
</script>
</html>