1.call
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
(1): 非严格模式
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b:undefined
fn.call(); // this:window a:undefined b:undefined
fn.call(null); // this=window a=undefined b=undefined
fn.call(undefined); // this=window a=undefined b=undefined
(2): 严格模式
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b:undefined
fn.call(); // this:window a:undefined b:undefined
fn.call(null); // this=null a=undefined b=undefined
fn.call(undefined);// this=undefined a=undefined b=undefined
2.apply
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.apply(obj,[1,2]); // this:obj a:1 b:2
fn.apply([1,2]); // this:1 a:2 b:undefined
fn.apply(); // this:window a:undefined b:undefined
fn.apply(null); // this=window a=undefined b=undefined
fn.apply(undefined); // this=window a=undefined b=undefined
3.bind
**fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
**fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行
***document.onclick = fn.call(obj);
// (this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined)
***document.onclick = fn.bind(obj);
// bind会把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行
总结:
相同点:--
都可以改变函数内部的this指向;
区别点:--
(1). call和apply会调用函数,并且改变函数内部的this指向;
(2). call和apply传递的参数不一样,call传递参数为 value1, value2 这种形式,apply传递的参数必须用数组包起来:[value1, value2];
(3). bind 不会调用函数,可以改变函数内部的this指向;
主要应用场景:
(1). call经常做继承;
(2). apply经常跟数组有关系,比如:借助于数学对象实现数组最大值最小值;
(3). bind 不会调用函数,但是还想改变this指向。比如:改变定时器内部的this指向;