call()
方法,可以指定函数内部this的指向(即函数执行时的所在的作用域),然后在所指定的作用域里面,调用该函数。var obj ={};
var f=function(){
return this;
};
f()===window //true
f.call(obj)===obj // true
上面代码,原先函数f的全局作用域是window,然后我们通过call方法,改变this指向,指向了对象obj,然后在obj的作用域运行函数f。call()
方法还可以接受多个参数,即func.call(thisValue,arg1,arg2,...)
第一个参数是this所指的那个对象.
2. apply()
方法与call方法相似,不同的事,它接受一个数组作为函数执行时的参数,func.apply(thisValue,[arg1,arg2,...])
function f(x,y){
console.log(x+y);
}
f.call(null,1,1);
f.apply(null,[1,1])
3.bind()
bind()
方法用于将函数体内的this绑定到某个对象上,然后返回一个新函数。
var d = new Date();
d.getTime() //.....
var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.
上面代码中,我们将d.getTime方法赋给变量print,然后调用print就报错了。这是因为getTime方法内部的this,绑定Date对象的实例,赋给变量print以后,内部的this已经不指向Date对象的实例了。
bind方法可以解决这个问题。
var print = d.getTime.bind(d);
print()//.....
bind方法的参数就是所要绑定this的对象
var counter = {
count:0,
inc:function(){
this.count++;
}
};
var func = counter.inc.bind(counter);
func();
counter.count // 1
var add = function (x, y) {
return x * this.m + y * this.n;
}
var obj = {
m: 2,
n: 2
};
var newAdd = add.bind(obj, 5);
newAdd(5) // 20
上面代码中,bind方法除了绑定this对象,还将add函数的第一个参数x绑定成5,然后返回一个新函数newAdd,这个函数只要再接受一个参数y就能运行了。
使用bind注意的问题
- 1. 每一次返回一个新函数
bind 方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。
element.addEventListener('click', o.m.bind(o));
正确的方法是写成下面这样:
var listener = o.m.bind(o);
element.addEventListener('click', listener);
// ...
element.removeEventListener('click', listener);
var counter = {
count: 0,
inc: function () {
'use strict';
this.count++;
}
};
function callIt(callback) {
callback();
}
callIt(counter.inc.bind(counter));
counter.count // 1
上面代码中,callIt方法会调用回调函数。这时如果直接把counter.inc传入,调用时counter.inc内部的this就会指向全局对象。使用bind方法将counter.inc绑定counter以后,就不会有这个问题,this总是指向counter。
引用资料网址:https://wangdoc.com/javascript/oop/this.html